bash:スクリプトと端末の動作が異なる(ループファイル)

bash:スクリプトと端末の動作が異なる(ループファイル)

ケースの説明で使用されているフォルダに基づいて、さまざまな検索条件を使用してファイルを繰り返したいと思います。オリジナル:

#!/bin/bash
case folder in
  "Testordner")
     search_filename=*_0_*.txt
      ;;
  "Ordner2")
     search_filename=*_65_*fg*.txt
     ;;
  *)
     ;;
esac
for files in $search_filename; do
  echo $files
done

私はLast Echoの検索基準に一致するファイルのリストを取得したいと思いました。代わりに検索基準自体を取得します。

テストするために、F="*.txt";for files in $F;do echo $files;donebash(操作してファイルのリストを取得)と同じスクリプト(出力を取得)で直接試しました*.txt$(..) ((..)) ${..}動作しません。)

なぜそんなことですか?どうすれば解決できますか?

喜んで助けを得るでしょう。カルロを祈ります


Ubuntu 22.04LTS、KDE/プラズマデスクトップ v5.1.16(1) を使用します。ターミナル: konsole v21.12.3

ベストアンサー1

Bashでnullglob無効になっている場合(通常はデフォルト)、一致がない場合、グローバルパターンはそれ自体で評価/拡張されます(たとえば、*.txtリテラル文字列として評価されます)。*.txt有効にするとnullglob(通常はスクリプトに適しています)、一致するものがない場合、グローバルパターンは空の文字列として評価/拡張されます。

スクリプトが別のディレクトリで実行されると、globは別々に拡張されます(もちろん、各ディレクトリに同じファイル名が存在しない限り)。

たとえば、

user@host:~ 0 $ touch {a,b,c}.log
user@host:~ 0 $ ls -l
total 0
-rw-------  1 user  staff  0 Jul 25 10:27 a.log
-rw-------  1 user  staff  0 Jul 25 10:27 b.log
-rw-------  1 user  staff  0 Jul 25 10:27 c.log
user@host:~ 0 $ shopt nullglob
nullglob        off
user@host:~ 1 $ echo *.log
a.log b.log c.log
user@host:~ 0 $ echo *.bak
*.bak
user@host:~ 0 $ shopt -s nullglob
user@host:~ 0 $ shopt nullglob
nullglob        on
user@host:~ 0 $ echo *.log
a.log b.log c.log
user@host:~ 0 $ echo *.bak

user@host:~ 0 $ 

無関係なメモで...少なくとも適切な場合は、コマンドラインの安全性と空白の処理を改善するのではなく、意図的な引用を慣用的echo "$files"にすることを検討してください。echo $files

たとえば、興味がある場合は、配列を使用することもできます。

#!/bin/bash -e

export PATH=/bin:/sbin:/usr/bin:/usr/sbin
shopt -s nullglob

declare -a files=()
case "$1" in
    'logs')
        files=(*.log)
        ;;
    'baks')
        files=(*.bak)
        ;;
    *)
        echo 'invalid argument' 1>&2
        exit 1
        ;;
esac

for f in "${files[@]}"; do
    echo "$f"
done

おすすめ記事