web-dev-qa-db-ja.com

ワイルドカードパラメータをbashファイルに渡す方法

ユーザーがワイルドカードを使用してディレクトリパスを渡すことができるbashスクリプトを記述しようとしています。

例えば、

bash show_files.sh *

このディレクトリ内で実行されたとき

drw-r--r--  2 root root  4.0K Sep 18 11:33 dir_a
-rw-r--r--  1 root root   223 Sep 18 11:33 file_b.txt
-rw-rw-r--  1 root root   106 Oct 18 15:48 file_c.sql

出力されます:

dir_a
file_b.txt
file_c.sql

現在の方法では、以下を出力します。

dir_a

の内容 show_files.sh

#!/bin/bash

dirs="$1"

for dir in $dirs
do
    echo $dir
done
31
eisaacson

bash show_files.sh *を呼び出す親シェルは、*を展開します。

スクリプトでは、次を使用する必要があります。

for dir in "$@"
do
    echo "$dir"
done

二重引用符は、ファイル名に含まれる複数のスペースなどが正しく処理されるようにします。

aの引数を反復する方法 bash シェルスクリプト


潜在的に混乱を招く補遺

*を展開するスクリプトを取得したい場合は、*がスクリプトに渡されることを確認する必要があります(他の回答のように引用符で囲みます)。その後、処理の適切なポイントで展開されることを確認します(簡単ではありません)。その時点で、配列を使用します。

names=( $@ )
for file in "${names[@]}"
do
    echo "$file"
done

二重引用符なしで$@を使用することはあまりありませんが、これは多かれ少なかれ正しいことです。トリッキーな部分は、スペースのあるワイルドカードをうまく処理できないことです。

考慮してください:

$ > "double  space.c"
$ > "double  space.h"
$ echo double\ \ space.?
double  space.c double  space.h
$

それはうまくいきます。しかし、それをスクリプトにワイルドカードとして渡してみてください...まあ、その時点でややこしくなります。

$2を個別に抽出する場合は、次を使用できます。

names=( $1 )
for file in "${names[@]}"
do
    echo "$file"
done
# ... use $2 ...
47

ワイルドカードを引用します。

bash show_files.sh '*'

または、1つだけでなく引数のリストをスクリプトに受け入れるようにします。

for dir in "$@"
do
    echo "$dir"
done

空白を含む要素を保持する特別な機能を保持するために、別の変数に割り当てるのではなく、"$@'を直接反復処理することをお勧めします。

9
chepner