Cvičím se substitucí parametrů v bash.
Napsal jsem následující fiktivní skript:
#!/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}/}"
V zásadě je vzor určen k odstranění poslední části názvu souboru
.
Výsledkem spuštění fiktivního skriptu je:
~$ ./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
zatímco eval
Zadání obsahu skriptu nebo ekvivalentně přímého vstupu této sekvence příkazů do interaktivního shellu má za následek:
~$ 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
Vzor '.[0-9]*.ext'
funguje, takže problém je jasně omezen na podřetězec '?(.random)'
. Problém může být s ?
, protože se jedná o vyhrazený znak v kontextu substituce parametrů. Pokud by to byl problém, očekával bych, že vzor buď selže, nebo uspěje stejně v obou případech.
Kde je pravděpodobně zřejmé úskalí?
Přijatá odpověď:
Problém může být v tom, že extglob
shell je nastaven v interaktivním shellu, ale ne v shellu skriptu.
$ 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
Můžete tedy zkusit zadat shopt -s extglob
hned za řádkem shebang ve skriptu.
Z referenční příručky Bash:
Pokud
extglob
možnost shell je povolena pomocíshopt
vestavěné,
je rozpoznáno několik rozšířených operátorů shody vzorů….
Složené vzory lze vytvořit pomocí jednoho nebo více z následujících dílčích vzorů:
?(PATTERN-LIST)
Odpovídá žádnému nebo jednomu výskytu daných vzorů.