GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Bash-Parameterersetzung:Befehlszeile vs. Skript?

Ich übe mit Parametersubstitution in bash.

Ich habe das folgende Dummy-Skript geschrieben:

#!/bin/bash

var1="/some/path/to/file/the_file.arbitrary.n.ext.0.random.ext"
var2="/some/path/to/file/the_file.arbitrary.n.ext.0.ext"

pattern='.[0-9]?(.random).ext'

echo "${pattern}"
echo "${var1/${pattern}/}"
echo "${var2/${pattern}/}"

Grundsätzlich soll das Muster den letzten Teil des Dateinamens
entfernen.

Das Ausführen des Dummy-Skripts führt zu:

~$ ./dummy.sh 
.[0-9]?(.random).ext
/some/path/to/file/the_file.arbitrary.n.ext.0.random.ext
/some/path/to/file/the_file.arbitrary.n.ext.0.ext

wohingegen eval Die Eingabe des Inhalts des Skripts oder äquivalent die direkte Eingabe dieser Befehlsfolge in die interaktive Shell führt zu:

~$ eval "$(cat dummy.sh)"
.[0-9]?(.random).ext
/some/path/to/file/the_file.arbitrary.n.ext
/some/path/to/file/the_file.arbitrary.n.ext

Das Muster '.[0-9]*.ext' funktioniert, also beschränkt sich das Problem eindeutig auf die Teilzeichenfolge '?(.random)' . Das Problem könnte bei ? liegen , da es sich um ein reserviertes Zeichen im Rahmen der Parameterersetzung handelt. Wenn dies jedoch das Problem wäre, würde ich erwarten, dass das Muster in beiden Fällen entweder fehlschlägt oder erfolgreich ist.

Wo ist die wahrscheinlich offensichtliche Falle?

Akzeptierte Antwort:

Das Problem kann sein, dass die Datei extglob Shell-Option wird in der interaktiven Shell gesetzt, aber nicht in der Skript-Shell.

$ shopt -u extglob
$ echo "${var1/${pattern}/}"
/some/path/to/file/the_file.arbitrary.n.ext.0.random.ext
$ shopt -s extglob
$ echo "${var1/${pattern}/}"
/some/path/to/file/the_file.arbitrary.n.ext

Sie können also versuchen, shopt -s extglob einzufügen direkt nach der Shebang-Zeile im Skript.

Aus dem Bash-Referenzhandbuch:

Wenn der extglob Die Shell-Option wird mit shopt aktiviert eingebaut,
werden mehrere erweiterte Mustervergleichsoperatoren erkannt….
Zusammengesetzte Muster können unter Verwendung eines oder mehrerer der folgenden Teilmuster gebildet werden:

?(PATTERN-LIST)
    Übereinstimmung mit null oder einem Vorkommen der angegebenen Muster.


Linux
  1. Bash =~ Regex und Https://regex101.com/?

  2. Bash Echo Die Befehlszeile wird in der Befehlszeile selbst ausgeführt (nicht in einem Skript)?

  3. Wann verwenden Sie die Klammererweiterung?

  4. Eingabe automatisch in die Befehlszeile eingeben?

  5. Wie man den Alias-Befehl in einem Bash-Skript oder einer Bashrc-Datei zum Laufen bringt

So lesen Sie eine Datei Zeile für Zeile in Bash

Bash-Quellbefehl

35 Bash-Skriptbeispiele

Bash-Scripting(III)

Bash-Skript fügt Text an die erste Zeile einer Datei an

Chroot schlägt fehl - Befehl `/bin/bash' kann nicht ausgeführt werden:Keine solche Datei oder Verzeichnis