我有一个关于在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'
我确定我在某个地方使用了错误的引号或括号,但我觉得我已经尝试了一切。感谢任何可以帮助新手的人。 :)
答案 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
的单独参数返回。