Skrypty Bash nie będą działać bez wpisania „bash” przed nim

11

Na naszym systemie szkolnym, jesteśmy w stanie uruchomić plików skryptów bez pisania bashlub cshlub co ty bez wskazania, jaki rodzaj skryptu jest. Jednak w Ubuntu muszę bash script.bashna przykład pisać . Czy jest to zawsze konieczne w Ubuntu, czy jest to jakieś ustawienie, które mogę zmienić?

muttley91
źródło
1
czy jest ustawiony jako plik wykonywalny?
jsolarski
tak, plik jest wykonywalny, dlatego sądzę, że po prostu działałby sam.
muttley91,
1
Jaki błąd pojawia się podczas pisania ./script? Czy jesteś pewien, że skrypt nie został zmieniony z edytora Windows umieszczającego dodatkowy znak na końcu linii? To złamałoby pierwszą linię wskazującą, że skrypt musi zostać wykonany przy pomocy bash.
João Pinto
1
Jak go uruchomić i jaki jest błąd?
użytkownik nieznany
+1 za nieużywanie .shskryptów bash. Zasadniczo jednak rozszerzenia plików nie są używane w skryptach wykonywalnych w świecie UNIX.
nyuszika7h

Odpowiedzi:

17
  1. Upewnij się, że zaczynasz skrypt od ./scriptpełnej ścieżki lub cokolwiek innego. Po prostu scriptmoże nie działać (działa, jeśli katalog jest w $PATH, jak /usr/bin), ponieważ w systemach UNIX nie jest nawyk posiadania bieżącego katalogu na swojej ścieżce (ze względów bezpieczeństwa i jest dobry!)

  2. Upewnij się, że skrypt jest wykonywalny, na przykład: chmod +x scriptsprawi, że będzie on wykonywalny.

  3. Upewnij się, że masz #!/bin/bashjako pierwszy wiersz w skrypcie. Upewnij się również, że nie jest edytowany za pomocą jakiegoś edytora systemu Windows, ponieważ często używa on „typu DOS” eol (koniec linii), który różni się od UNIX (jeśli powyższa lista kontrolna jest OK, ale masz „zły” interpreter: nie ma takiego pliku lub katalogu ”, nawet jeśli jest to / bin / bash, jest to często powód, ponieważ nie można go wydrukować - więc zazwyczaj go nie widzisz - \ r będzie traktowany jako część ścieżka tłumacza)

Inni już wspominali: ważne jest, aby /bin/bashużywać funkcji bash, również /bin/shbył dowiązany do /bin/bash, ale teraz (o ile zauważyłem) teraz jest dowiązany do, dashktóry nie zapewni kompatybilności bash, tylko POSIX sh. Jest to dość ważne, nawet dość drogie oprogramowanie w naszej firmie ma ten problem: skrypty zawierają #!/bin/shjako pierwszą linię, ale zależy to również od funkcjonalności bash.

LGB
źródło
Będę musiał uruchomić tak: ./script, jak odkryłem. Jest to lepsze niż za każdym razem wpisywanie „bash” i ma to sens. Wierzę, że wiedziałem o tym wcześniej, to po prostu wymknęło mi się z głowy. No cóż, dzięki!
muttley91,
Teoretycznie możesz umieścić bieżący katalog roboczy w zmiennej PATH, aby następnie użyć tylko „skryptu” zamiast „./script”, ale ostrzegam: tak naprawdę nie jest to nawyk w systemach UNIX i może to być problem z bezpieczeństwem ! Poza tym w szkole nie jest miło uczyć się rzeczy w sposób, który nigdy nie był rozwiązaniem w systemach UNIX, więc unikałbym tego rozwiązania ...
LGB
1
Lub, najlepiej, #!/usr/bin/env bashktóry jest nieco bardziej przenośny.
Sparhawk
4

Upewnij się, że pierwszy wiersz pliku brzmi:

#!/bin/bash

Jeśli shebang jest #!/bin/sh, nie powinieneś używać żadnych funkcji specyficznych dla bash, tylko funkcje POSIX. Nawet jeśli /bin/shjest dowiązaniem symbolicznym bash, bash będzie działał w trybie zgodności z POSIX, gdy będzie uruchomiony jako sh, wyłączając niektóre (ale nie wszystkie) funkcje bash.

Oczywiście musisz także upewnić się, że skrypt jest wykonywalny.

geirha
źródło
Nie, i tak nastawiłem się na walkę z przyzwyczajenia.
muttley91,
0

Alternatywnym, zdecydowanie odradzanym sposobem jest dodawanie .do PATH.

PATH=".:$PATH"

lub

PATH="$PATH:."

Problem z tym podejściem polega na tym, że w pierwszym przypadku dowolne polecenie systemowe można zastąpić plikami wykonywalnymi z bieżącego katalogu, a w drugim przypadku nieznane polecenia mogą zostać zastąpione.

Rozważ następujące:

Plik: ls

#!/bin/bash

./my_malicious_script &>/dev/null
/bin/ls "$@"

Najprawdopodobniej nawet tego nie zauważysz, dopóki nie będzie za późno.

nyuszika7h
źródło
1
Wybór słowa jest tutaj nieco mylący. Polecenia nie zostaną zastąpione. Jeśli masz komendę w bieżącym katalogu roboczym, która ma taką samą nazwę jak ta, która mieszka w katalogach systemowych, powiedzmy echona przykład, że ta w twoim katalogu zostanie użyta po prostu dlatego, że ten katalog jest ustawiony w PATHzmiennej przed /bin. Shell po prostu szuka poleceń w poszczególnych katalogach w zależności od ich kolejności PATHi niczego nie zastępuje / nie niszczy. Ale tak, ma to implikacje
Sergiy Kolodyazhnyy