我有一个带有以下参数的 rsync 命令:
rsync -avz --{partial,stats,delete,exclude=".*"}
我想将该参数放入变量中,以便在脚本中重用它。像这样的东西:
#!/bin/bash
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
$VAR /dir1 /dir2
我尝试过使用引号、单引号、括号,但没有成功。
答案1
将复杂命令放入变量中绝不是推荐的方法。看BashFAQ/050 - 我试图将命令放入变量中,但复杂的情况总是失败!
如果您只是决定使用函数而不是变量并向其传递参数,那么您的要求就会变得非常简单。
就像是
rsync_custom() {
[ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
rsync -avz --{partial,stats,delete,exclude=".*"} "$@"
}
现在将所需的参数传递给它
rsync_custom /dir1 /dir2
函数定义在某种程度上非常简单,我们首先使用$#
不应为零的变量检查输入参数计数。我们抛出一条错误消息,指出未提供任何参数。如果存在有效参数,则"$@"
表示提供给函数的实际参数。
如果这是一个您经常使用的函数,即在脚本/命令行中,请将其添加到 shell 启动文件中,.bashrc
例如.bash_profile
。
或者如前所述,可能值得将大括号扩展扩展为单独的参数以获得更好的可读性,因为
rsync_custom() {
[ "$#" -eq 0 ] && { printf 'no arguments supplied' >&2; exit 1 ; }
rsync -avz --partial --stats --delete --exclude=".*" "$@"
}
答案2
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
-avz
这尝试使用参数等运行命令--partial
,并在环境中设置为。--stats
VAR
rsync
VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'
带引号的形式不起作用,因为大括号不会在引号中展开,也不会在赋值内部展开,并且在变量展开后也不会展开。
如果需要将命令行参数存储在变量中,请使用数组:
args=(rsync -avz --{partial,stats,delete,exclude=".*"})
现在"${args[@]}"
将扩展为rsync
、-avz
、--partial
等作为不同的单词。
数组还允许您根据需要将选项附加到列表中,因此您可以例如:
args=(this that)
if something ; then
args+=(another_arg)
fi
"$cmd" "${args[@]}"
也可以看看:
答案3
您至少可以将部分选项保存在变量中:
opts=$(echo --{ignore-case,word-regexp,count,exclude="sys*.*"})
测试很重要,因为屏蔽可能很困难:
echo $opts
--ignore-case --word-regexp --count --exclude="sys*.*"
grep $opts bytes *.log
由于有多种选择,例如使用历史记录、使用别名、使用函数,因此我无法想到明显的用例。不同程序之间很少共享复杂的选项,因此对于交互式 shell 的临时解决方案,别名似乎是更好的方法:
alias cgrep='grep --ignore-case --word-regexp --count --exclude="sys*"'
cgrep bytes *.log
您的样品
VAR=rsync -avz --{partial,stats,delete,exclude=".*"}
无法工作,因为作业在第一个空白处结束。你必须掩盖空白:
VAR='rsync -avz --{partial,stats,delete,exclude=".*"}'
使用 --delete 选项进行测试是非常危险的,不是吗?由于选项可以再次包含“,”和单引号,因此屏蔽很快就会变得困难。我会选择别名或依赖历史。
别名可以存储在 ~/.bashrc 文件中,以便在多个会话中连续使用。函数也可以存储在 bashrc 中,但是如果您想处理参数,则只需要它们,传递到函数中以在其中进行评估。