shopt funktioniert in der Befehlszeile, nicht gefunden, wenn es in einem Skript ausgeführt wird

13

Ich schreibe ein Skript, um einige Dateien zu kopieren und versuche, shopt -s dotglob cp zu ermöglichen, Dotfiles wie .jshintund so weiter zu kopieren.

Ich kann shopt -s dotglobohne Fehler direkt an einer Bash-Eingabeaufforderung ausgeführt werden. Das Ausführen des Skripts löst jedoch den Fehler aus:

script.sh: 81: script.sh: shopt: not found

Ich führe dieses Skript in der Bash-Shell mit dem Shebang-Header aus #!/usr/bin/env bash. Fehlerzeile:

shopt -s dotglob
cp -r $TEMP/img/* $TARGET/img/
cp -r $TEMP/js/* $TARGET/js/
cp -r $TEMP/less/* $TARGET/less/

Sie finden bei Google keine hilfreichen Informationen. Haben Sie eine Idee, wo das Problem liegt?

Kurtosis
quelle
Vielen Dank für die Erinnerung, ausgewählte Antworten für alles, was ich konnte. Neben dieser Frage gibt es noch eine, die noch keine gute Antwort hat.
Kurtosis
3
Versuchen Sie es mit dem einfacheren #!/bin/bashHeader?
ish
Und welche Ubuntu-Version?
ish
2
@izx, das ist die richtige Antwort, shoptist eine eingebaute Bash, shhat keine shoptund die Fehlermeldung sieht aus wie eine Fehlermeldung von dash. Wahrscheinlich wird hier ein Bash-Skript ausgeführt sh(was in Ubuntu dashstandardmäßig der Fall ist ). Selbst wenn shes sich um einen Symlink handelt, bashist das Ausführen eines Bash-Skripts shnicht dasselbe wie das Ausführen mit bash.
Geirha

Antworten:

22

Um eine Antwort aus den Kommentaren zu bilden:

Viele Leute laufen aus Gewohnheit mit ihren Skripten shanstatt bash. Dies ist eine gute Vorgehensweise, wenn Portabilität ein Problem darstellt, aber viele Leute tun dies, weil sie etwas kopieren, was sie gesehen haben, ohne es zu verstehen.

Sofern Ihr Skript nicht auf einem Nicht-Desktop-Linux-System ausgeführt werden muss (z. B. das Ausführen von Shell-Skripten auf Android-Geräten ist völlig anders), empfehle ich, zu Beginn die Bash-Shebang-Zeile zu verwenden:

#!/bin/bash

Diese Zeile bestimmt, wenn es sich um die erste Zeile im Skript handelt, welcher Interpreter (Shell wie bash oder sh, Python usw.) zur Ausführung aufgerufen wird. Wenn Sie die obige Zeile verwenden, erhalten Sie (fast) dasselbe Verhalten wie über die Befehlszeile, vorausgesetzt, Sie verwenden die Standard-Shell. Wenn Sie aus Gründen der Portabilität oder Präferenz eine andere shebang-Zeile verwenden, beachten Sie, dass Sie die Dokumentation der von Ihnen referenzierten Shell konsultieren müssen, auch wenn die von Ihnen referenzierte Shell ein Symlink zu Bash ist.

Scott Severance
quelle
5
Um vollständig systemübergreifend zu sein, bevorzuge ich: Da #!/usr/bin/env bash es die Aufgabe von env ist, zu wissen, welche Bash verwendet werden soll (falls Sie sie beispielsweise gepatcht haben).
Shrikeh
-1

Sie müssen zsh beenden und bash wie folgt aktivieren:

exec bash

Führen Sie den Befehl aus

source ~/.bashrc

Danach können Sie zsh reaktivieren:

exec zsh

Ich hoffe, das hilft

David Kabii
quelle
Hmmm. 1) Ich glaube nicht, dass das OP zsh verwendet hat, 2) AFAIK ~/.basrcwird in diesem Fall beim Start durch Bash ausgeführt, sodass es nicht erforderlich ist, es explizit aufzurufen. 3) Wo wird der Befehl des OP ausgeführt? und 4) durch execzweimaliges Verwenden verlieren Sie alle Umgebungsänderungen, die Sie in der anfänglichen zsh-Shell vorgenommen haben. Dies würde nicht passieren, wenn Sie nur bash aufrufen würden.
Xenoid
In meinem Fall war es erforderlich, Umgebungsänderungen zu erfassen, und die Änderungen blieben bestehen. Ich habe den Computer gerade neu gestartet und alle meine Änderungen werden beibehalten. Vielleicht ist es nur spezifisch für eine Anakonda, die ich
einrichten wollte