Posixシェルスクリプト - 複数行のコマンド出力を変数に保存する

Posixシェルスクリプト - 複数行のコマンド出力を変数に保存する

複数行の変数を含むコマンド出力を端末に直接保存すると、次の結果が表示されます。

$ dirs=$(ls -1d /mnt/*/)
$ echo $dirs
/mnt/ext4/ /mnt/local/ /mnt/remote/ /mnt/test/
$ echo "$dirs"
/mnt/ext4/
/mnt/local/
/mnt/remote/
/mnt/test/

ただし、posixシェルスクリプトでこれを使用すると結果が異なります。これはスクリプトです。

#!/bin/sh

dirs=$(ls -1d $1)
echo "inline"
echo $dirs
echo "multiline"
echo "$dirs"

これはスクリプト出力です

$ ./test.sh /mnt/*/
inline
/mnt/ext4/
multiline
/mnt/ext4/

shの代わりにbashを使用しても、この現象が発生します。

出力全体を維持するために出力をls -1d /mnt/*/変数に保存する方法を知っている人はいますか?
forループ内で4つのディレクトリパスをそれぞれ解析したいと思います。

答え1

$ ./test.sh /mnt/*/

ここで glob は、コマンドラインで手動で作成するのと同じように、別の引数でディレクトリ名に展開されます。

$ ./test.sh /mnt/ext4/ /mnt/local/ /mnt/remote/ /mnt/test/

ただし、スクリプト自体内では最初のパラメータを引用するだけです$1

dirs=$(ls -1d $1)

すべてのパラメータを引用するには"$@"(引用符を含む)を使用してください。

ただし、ディレクトリ名を使用してここで実行するすべての操作はそのディレクトリで実行されます。lsこれは同じ名前(別の行にある)を印刷するだけです。したがって、引数リストを文字列にしたい場合は、lsコマンドをまったく実行する必要はなく、割り当てを行うだけですdirs="$@"

しかし、すべてではありませんが、ほとんどの場合、場所引数にファイル名のリストを保持し、ループを使用して繰り返すことをお勧めします。

for f in "$@"; do ...

または

for f
do ...

ファイル名にはスペースを含めることができ、名前を単一の文字列に連結すると、名前内のスペースの意味が失われます。foo bar doo3つのファイルであっても2つのファイルfoo bardoo

関連情報