Posix shell 脚本 - 将多行命令输出保存到变量

Ark*_*aik 0 command-line shell shell-script 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/
Run Code Online (Sandbox Code Playgroud)

但是,当从 posix shell 脚本使用它时,结果是不同的。这是脚本

#!/bin/sh

dirs=$(ls -1d $1)
echo "inline"
echo $dirs
echo "multiline"
echo "$dirs"
Run Code Online (Sandbox Code Playgroud)

这是脚本输出

$ ./test.sh /mnt/*/
inline
/mnt/ext4/
multiline
/mnt/ext4/
Run Code Online (Sandbox Code Playgroud)

即使我使用 bash 而不是 sh,也会发生这种情况。

有谁知道我如何将输出保存ls -1d /mnt/*/到保持完整输出的变量中?
我想解析 for 循环中的四个目录路径中的每一个。

ilk*_*chu 5

$ ./test.sh /mnt/*/
Run Code Online (Sandbox Code Playgroud)

此处的 glob 扩展为目录名称作为单独的参数,就像您在命令行上手动写出它们一样:

$ ./test.sh /mnt/ext4/ /mnt/local/ /mnt/remote/ /mnt/test/
Run Code Online (Sandbox Code Playgroud)

但是,在脚本本身中,您只引用了第一个参数$1

dirs=$(ls -1d $1)
Run Code Online (Sandbox Code Playgroud)

如果要引用所有参数,请使用"$@"(带引号)。

但是,您在此处对目录名称所做的ls只是在它们上运行,它只是打印出相同的名称(尽管在不同的行上)。因此,如果您只想将参数列表作为字符串,则根本不需要运行该ls命令,只需将dirs="$@".

尽管如此,在大多数情况下,如果不是所有情况,最好将文件名列表保留在位置参数中,并使用

for f in "$@"; do ...
Run Code Online (Sandbox Code Playgroud)

或者

for f
do ...
Run Code Online (Sandbox Code Playgroud)

请注意,文件名可能包含空格,当您将名称连接到单个字符串时,您会失去名称中空格的含义。foo bar doo可能是三个文件,或者两个文件foo bardoo.