【问题标题】:Using variables as function arguments in Bash在 Bash 中使用变量作为函数参数
【发布时间】:2014-02-03 13:16:25
【问题描述】:

我有一个关于在 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'

我确定我在某处使用了错误类型的引号或括号,但我觉得我已经尝试了所有方法。感谢任何可以帮助新手的人。 :)

【问题讨论】:

    标签: bash variables quotes


    【解决方案1】:

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

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

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

    然后说:

    scp -r "$FILELIST"  $DESTINATION
    

    【讨论】:

    • 嗯,你肯定让我更接近解决方案。通过您的方法,FILELIST 得到了扩展,但是 scp 的参数仍然出现在单引号内,所以在我的情况下(/foo 是当前目录.DESTINATION 引用主目录~,这些符号未得到解析。我不得不修改您的解决方案以阅读 scp -r $(eval echo "$FILELIST") $(eval echo $DESTINATION) 才能工作。感谢您的帮助!
    【解决方案2】:

    如果您将大括号或 *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

    【讨论】:

    • 我最终使用了更接近 devnull 的方法,但感谢您的帮助并教会了我一些关于 bash 数组的新知识! =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 2021-12-01
    • 2021-09-29
    • 1970-01-01
    • 2016-08-10
    相关资源
    最近更新 更多