在Bash中使用变量作为函数参数

时间:2014-01-15 07:12:40

标签: bash variables quotes

我有一个关于在Bash脚本中使用变量作为命令输入的简单问题。我想编写一个脚本,自动将目录的某些内容foo复制到另一个目录ssh中通过bar连接的嵌入式计算机。

换句话说,我想将以下命令转换为更易于维护的脚本:

ssh -r /foo/{file1,file2,dir1,*.h,*.hpp,*.c,*.cpp} uname@1.1.1.1:~/bar

到目前为止,我有以下内容:

#!/bin/bash

SOURCE='/foo';
FILES='{file1,file2,dir1,*.h,*.hpp,*.c,*.cpp}';
DESTINATION='uname@1.1.1.1:~/bar';

set -x
scp -r $SOURCE/$FILES  $DESTINATION
set +x

但是,这将执行:

ssh -r '/foo/{file1,file2,dir1,*.h,*.hpp,*.c,*.cpp}' 'uname@1.1.1.1:~/bar'

我确定我在某个地方使用了错误的引号或括号,但我觉得我已经尝试了一切。感谢任何可以帮助新手的人。 :)

2 个答案:

答案 0 :(得分:2)

manual会告诉您 Brace扩展在任何其他扩展之前执行...

如果你想在命令中使用变量,我认为你没有选择,只能在这里使用eval

SOURCE='/foo';
FILES='{file1,file2,dir1,*.h,*.hpp,*.c,*.cpp}';
FILELIST="$(eval echo "${SOURCE}"/"${FILES}")"

后来说:

scp -r "$FILELIST"  $DESTINATION

答案 1 :(得分:1)

如果将大括号或* s放在引号内,它们将不会被shell展开。所以,使用:

scp -r "$SOURCE/"{file1,file2,dir1,*.h,*.hpp,*.c,*.cpp}  $DESTINATION

如果你真的想在调用scp之前定义文件列表,那么使用bash数组:

filelist=( "$SOURCE/"{file1,file2,dir1,*.h,*.hpp,*.c,*.cpp} )

scp -r "${filelist[@]}" $DESTINATION

此处,filelist是一个数组,而"${filelist[@]}"是bash的特殊咒语,用于将列表中的每个文件名作为scp的单独参数返回。