Skrypt Bash wypisuje „Polecenie nie znaleziono” w pustych wierszach

112

Za każdym razem, gdy uruchamiam skrypt przy użyciu bash scriptname.shwiersza poleceń w Debianie, otrzymuję Command Not foundwynik skryptu.

Skrypt działa, ale Command Not Foundna ekranie zawsze jest wypisywana instrukcja dla każdego pustego wiersza. Każda pusta linia powoduje, że polecenie nie zostało znalezione.

Uruchamiam skrypt z /varfolderu.

Oto skrypt:

#!/bin/bash

echo Hello World

Uruchamiam go, wpisując:

bash testscript.sh

Dlaczego tak się stało?

David
źródło
Poważnie, w sieci jest pełno takich skarg. Shell jest bardzo słabym i kiepskim tłumaczem. Niewiele tu i tam i zawodzi. Musisz obserwować nawet wszystkie białe spacje w skrypcie. Mój skrypt nie działał z powodu niewidocznego znaku nowego wiersza. Prawdopodobnie jest to tylko język skryptowy, w którym liczą się białe spacje!
Atul
1
Służy bash -x scriptname.shdo śledzenia błędu. - W moim przypadku był to plik sh zapisany pod Windows z VSCode i zakończeniami linii jako "CRLF". W VSCode w prawym dolnym rogu można zmienić terminator linii z „CRLF” na „LF”. Przesłałem ten plik i mogłem go ostatecznie uruchomić z bash scriptname.sh.
Kai Noack,
Jest to z pewnością duplikat stackoverflow.com/questions/39527571/ ... ale wiele odpowiedzi tutaj wyjaśnia szereg innych sytuacji, w których otrzymujesz komunikat „polecenie nie znaleziono” z innych powodów. Odwiedzającym zaleca się przeczytanie wszystkich odpowiedzi, jeśli problem nie dotyczy konkretnie pustych wierszy.
tripleee

Odpowiedzi:

162

Upewnij się, że pierwsza linia to:

#!/bin/bash

Podaj swoją ścieżkę do uderzenia, jeśli tak nie jest /bin/bash


Spróbuj biegać:

dos2unix script.sh

To spowoduje konwersję końcówek linii itp. Z formatu Windows do formatu uniksowego. tj. usuwa \ r (CR) z końców linii, aby zmienić je z \r\n (CR+LF)na \n (LF).

Więcej szczegółów na temat dos2unixpolecenia (strona podręcznika )


Inny sposób sprawdzenia, czy plik jest w formacie dos / Win:

cat scriptname.sh | sed 's/\r/<CR>/'

Wynik będzie wyglądał mniej więcej tak:

#!/bin/sh<CR>
<CR>
echo Hello World<CR>
<CR>

Spowoduje to wyświetlenie całego tekstu pliku z <CR>wyświetleniem dla każdego \rznaku w pliku.

chown
źródło
Prawdopodobnie nie jest to konieczne, ponieważ używa go bezpośrednio bash scriptname.sh(ale nadal jest to dobra praktyka).
paxdiablo
1
Cześć #! / Bin / bash to pierwsza linia mojego skryptu
David
1
@chown - miałem ten sam problem na Macu. Natknąłem się na ten post. Nie jestem pewien, czy pomogło to OP, czy nie. Ale twoje rozwiązanie pomogło mi.
Prashant
1
dzięki. To był dokładnie problem, z jakim miałem do czynienia. Dzięki tym odpowiedziom to działa.
zabitybylucifer
5
Jak możesz napisać odpowiedź na pytanie programistyczne podczas jazdy?
Omar Tariq,
61

Możesz użyć bash -x scriptname.shdo śledzenia.

liszaj
źródło
47

Natknąłem się też na podobny problem. Wydaje się, że problemem są uprawnienia. Jeśli to zrobisz ls -l, możesz być w stanie zidentyfikować, że twój plik NIE ma włączonego bitu wykonania. To NIE pozwoli na wykonanie skryptu. :)

Jak dodał @artooro w komentarzu:

Aby rozwiązać ten problem, uruchom chmod +x testscript.sh

Lypso345
źródło
4
Aby rozwiązać ten problem, uruchomchmod +x testscript.sh
artooro
To była odpowiedź, która zadziałała dla mnie: Zawsze mówiono mi, że nie mam pozwolenia, więc zgodziłem się i powiedziano mi, że nie znaleziono polecenia. Nie pomyślałem, żeby sprawdzić uprawnienia.
DiamondDrake
1
Dzięki Lypso345, to rozwiązało problem, który miałem.
ammills01
chmod 777 testscript.sh FTW
GeneCode,
16

To może być trywialne i niezwiązane z pytaniem OP, ale często myliłem się na początku, kiedy uczyłem się pisania skryptów

VAR_NAME = $(hostname)
echo "the hostname is ${VAR_NAME}"  

Spowoduje to wyświetlenie odpowiedzi „nie znaleziono polecenia”. Prawidłowym sposobem jest wyeliminowanie przestrzeni

VAR_NAME=$(hostname)
altamont
źródło
11

Jeśli skrypt wykonuje swoje zadanie (względnie) dobrze, to działa poprawnie. Twoim problemem jest prawdopodobnie pojedyncza linia w pliku odwołująca się do programu, którego nie ma w ścieżce, nie jest zainstalowany, ma błędną pisownię lub coś podobnego.

Jednym ze sposobów jest umieszczenie set -xna górze skryptu lub uruchomienie go za pomocą bash -xzamiast tylko bash- spowoduje to wyświetlenie wierszy przed ich wykonaniem i zwykle wystarczy spojrzeć na dane wyjściowe polecenia bezpośrednio przed błędem, aby zobaczyć, co powoduje problem

Jeśli, jak mówisz, to puste wiersze powodują problemy, możesz sprawdzić, co się w nich dzieje . Biegać:

od -xcb testscript.sh

i upewnij się, że nie ma „niewidzialnych” zabawnych znaków, takich jak CTRL-M(powrót karetki), które można uzyskać za pomocą edytora systemu Windows.

paxdiablo
źródło
+1 dla polecenia „od”! Super, nie wiedziałem o tym! Dzięki!
chown
11

W Bash dla Windows próbowałem niepoprawnie uruchomić

run_me.sh 

bez ./ na początku i otrzymałem ten sam błąd.

Dla osób z tłem Windows poprawny formularz wygląda na zbędny:

./run_me.sh
Michael Freidgeim
źródło
8

użyj dos2unixw swoim pliku skryptu.

bash-o-logist
źródło
6

aby wykonać, musisz podać na przykład pełną ścieżkę do tego

/home/Manuel/mywrittenscript
Masood Moghini
źródło
Rzeczywiście, powłoka w ogóle nie dba o rozszerzenia plików. Nie jestem pewien, czy warto to opublikować jako oddzielną odpowiedź.
tripleee
oczywiście. w systemie plików linux w przeciwieństwie do rozszerzeń Windows są używane tylko jako część nazwy i nic nie mówią o zawartości pliku. w moim przypadku nie mogę mówić o ograniczeniach.
Masood Moghini
6

Jeśli masz Notepad ++ i otrzymujesz ten komunikat o błędzie .sh: "polecenie nie znaleziono" lub ten komunikat o błędzie autoconf "wiersz 615: ../../autoconf/bin/autom4te: Nie ma takiego pliku lub katalogu" .

Na swoim Notepad ++ przejdź do Edycja -> Konwersja EOL, a następnie sprawdź Macinthos (CR) . Spowoduje to edycję plików. Zachęcam też do sprawdzania wszystkich plików tym poleceniem, bo już niedługo taki błąd wystąpi.

Juniar
źródło
Dzięki za to. W moim przypadku uruchamiałem skrypt na dystrybucji busybox linux. Wystąpił ten sam błąd „nie znaleziono” we wszystkich pustych wierszach w moich skryptach. miał również problemy z instrukcją if / else. zmiana EOL w Notepad ++ na Unix naprawiła to.
GeneCode,
4

Miałem ten sam problem. Niestety

dos2unix winfile.sh
bash: dos2unix: command not found

więc zrobiłem to, aby przekonwertować.

 awk '{ sub("\r$", ""); print }' winfile.sh > unixfile.sh

i wtedy

bash unixfile.sh
Eugene Cuz
źródło
2

Problemy z uruchamianiem skryptów mogą być również związane z niewłaściwym formatowaniem poleceń wielowierszowych, na przykład jeśli po łamaniu linii „\” występują białe znaki. Np. To:

./run_me.sh \ 
--with-some parameter

(zwróć uwagę, że dodatkowa spacja po znaku „\”) spowoduje problemy, ale po usunięciu tego miejsca będzie działać idealnie.

Marek Wysocki
źródło
0

Miałem też niektóre z plików Cannot execute command. Wszystko wyglądało poprawnie, ale tak naprawdę miałem &nbsp;przed rozkazem nierozerwalną przestrzeń, której oczywiście nie można było dostrzec gołym okiem:

if [[ "true" ]]; then
  &nbsp;highlight --syntax js "var i = 0;"
fi

Który w Vimie wyglądał tak:

if [[ "true" ]]; then
  highlight --syntax js "var i = 0;"
fi

Dopiero po uruchomieniu sprawdzania skryptów Bash shellcheckznalazłem problem.

Stefan van den Akker
źródło
shellcheckjest dostępny on-line, chociaż oczywiście musisz dokładnie skopiować i wkleić skrypt, aby to pomogło. shellcheck.net
tripleee
0

Natknąłem się na to dzisiaj, z roztargnieniem kopiując wiersz polecenia dolara $(przed ciągiem poleceń) do skryptu.

CNSKnight
źródło
-1

Dodaj bieżący katalog (.) Do PATH, aby móc wykonać skrypt, po prostu wpisując jego nazwę, która znajduje się w bieżącym katalogu:

PATH=.:$PATH
Mike Goethals
źródło
1
Jest to uważane za lukę w zabezpieczeniach. NIE DODAWAJ .DO SWOJEJ ŚCIEŻKI.
gniourf_gniourf,
Wyjaśnienie, dlaczego ta „odpowiedź” jest złym pomysłem: superuser.com/questions/156582/ ...
jmng
-1

Możesz chcieć zaktualizować pliki .bashrc i .bash_profile za pomocą aliasów, aby rozpoznać wprowadzane polecenie.

Pliki .bashrc i .bash_profile są plikami ukrytymi, prawdopodobnie znajdującymi się na dysku C:, na którym zapisujesz pliki programu.

Kean Amaral
źródło