变量中的命令不 运行 文件名中有空格
Command in variable doesn't run with witespaces in filenames
我喜欢 linux shell 中将命令存储到变量中的可能性:
mycommand="cp fileOne.txt fileTwo.txt /home/myself/targetdir"
$mycommand
执行得很好。
但是如何处理文件名中的空格?
以下备选方案 运行ns 好:
cp file\ One.txt file\ Two.txt /home/myself/targetdir
# and also
cp "file One.txt" "file Two.txt" /home/myself/targetdir
现在我也尝试将其放入我的变量中(调用 $mycommand
)。
但是我下面的 none 人尝试 运行:
mycommand="cp file\ One.txt file\ Two.txt /home/myself/targetdir"
mycommand="cp \"file One.txt\" \"file Two.txt\" /home/myself/targetdir"
mycommand="cp 'file One.txt' 'file Two.txt' /home/myself/targetdir"
mycommand='cp "file One.txt" "file Two.txt" /home/myself/targetdir'
在所有选项中,参数由空格分隔,文件 "file" 将找不到。
我可以做什么?
(我想知道为什么我找不到关于此问题的类似问题...)
编辑:
使用 set -x
我得到 cp
的以下行,具体取决于上面的尝试:
+ cp 'file\' One.txt 'file\' Two.txt /home/myself/targetdir
+ cp '"file' 'One.txt"' '"file' 'Two.txt"' /home/myself/targetdir
+ cp ''\''file' 'One.txt'\''' ''\''file' 'Two.txt'\''' /home/myself/targetdir
+ cp '"file' 'One.txt"' '"file' 'Two.txt"' /home/myself/targetdir
每次尝试的第一行输出,从德语翻译成英语,是:
cp: cannot stat 'file\': No such file or directory
cp: cannot stat '"file'’: No such file or directory
cp: cannot stat ''\''file': No such file or directory
cp: cannot stat '"file': No such file or directory
似乎命令字符串由空格分隔,忽略了 ""
和 \
- 但为什么呢?我该如何避免这种情况?
我找到了解决方案:
eval $mycommand
并且,对于其他场景可能更安全,
eval "$mycommand"
将按预期工作。
(使用 eval
变量将在执行前展开。)
一个实际使用的例子:
提供了一个连接 pdf 文件的工具,例如 pdfunite
:
for file in *.pdf; do
inputfiles="$inputfiles \"$file\""
done
eval "pdfunite $inputfiles mergedOutputfile.pdf"
编辑:
看到这个旧的 post,我正在添加我现在使用的更好的解决方案 - 在 @chepner link posted 中已经提到:
使用一个数组:
inputfiles=()
for file in *.pdf; do
inputfiles+=("$file")
done
pdfunite "${inputfiles[@]}" "/path/to/merged outputfile.pdf"
(好像没有回答第一个问题,但很多时候这个场景就是问题的来源)
我喜欢 linux shell 中将命令存储到变量中的可能性:
mycommand="cp fileOne.txt fileTwo.txt /home/myself/targetdir"
$mycommand
执行得很好。
但是如何处理文件名中的空格?
以下备选方案 运行ns 好:
cp file\ One.txt file\ Two.txt /home/myself/targetdir
# and also
cp "file One.txt" "file Two.txt" /home/myself/targetdir
现在我也尝试将其放入我的变量中(调用 $mycommand
)。
但是我下面的 none 人尝试 运行:
mycommand="cp file\ One.txt file\ Two.txt /home/myself/targetdir"
mycommand="cp \"file One.txt\" \"file Two.txt\" /home/myself/targetdir"
mycommand="cp 'file One.txt' 'file Two.txt' /home/myself/targetdir"
mycommand='cp "file One.txt" "file Two.txt" /home/myself/targetdir'
在所有选项中,参数由空格分隔,文件 "file" 将找不到。
我可以做什么?
(我想知道为什么我找不到关于此问题的类似问题...)
编辑:
使用 set -x
我得到 cp
的以下行,具体取决于上面的尝试:
+ cp 'file\' One.txt 'file\' Two.txt /home/myself/targetdir
+ cp '"file' 'One.txt"' '"file' 'Two.txt"' /home/myself/targetdir
+ cp ''\''file' 'One.txt'\''' ''\''file' 'Two.txt'\''' /home/myself/targetdir
+ cp '"file' 'One.txt"' '"file' 'Two.txt"' /home/myself/targetdir
每次尝试的第一行输出,从德语翻译成英语,是:
cp: cannot stat 'file\': No such file or directory
cp: cannot stat '"file'’: No such file or directory
cp: cannot stat ''\''file': No such file or directory
cp: cannot stat '"file': No such file or directory
似乎命令字符串由空格分隔,忽略了 ""
和 \
- 但为什么呢?我该如何避免这种情况?
我找到了解决方案:
eval $mycommand
并且,对于其他场景可能更安全,
eval "$mycommand"
将按预期工作。
(使用 eval
变量将在执行前展开。)
一个实际使用的例子:
提供了一个连接 pdf 文件的工具,例如 pdfunite
:
for file in *.pdf; do
inputfiles="$inputfiles \"$file\""
done
eval "pdfunite $inputfiles mergedOutputfile.pdf"
编辑:
看到这个旧的 post,我正在添加我现在使用的更好的解决方案 - 在 @chepner link posted 中已经提到:
使用一个数组:
inputfiles=()
for file in *.pdf; do
inputfiles+=("$file")
done
pdfunite "${inputfiles[@]}" "/path/to/merged outputfile.pdf"
(好像没有回答第一个问题,但很多时候这个场景就是问题的来源)