我遇到一个奇怪的问题,我认为它与文件/目录通配
有关echo "tar -zcvf $file $base/$target $exclude_args"
cd $base && tar -zcvf $file $base/$target $exclude_args
tar -zcvf www_2017-04-24.tar.gz /var/www --exclude '/var/www/bak/*/*' --exclude '/var/www/test'
运行脚本时,省略排除路径(每个目录都是gzip压缩)
直接从putty运行输出时,/var/www/bak/*/*
下的目录从gzip中排除
parse_exclude_paths (){
# escape forward slashes to avoid the paths to expand
args=$(echo "$exclude" | sed 's,/,\\\/,g')
args=$(printf " --exclude '%s'" $args)
# strip escapes
echo "$args" | sed 's,\\\/,/,g'
}
exclude="/var/www/bak/*/* /var/www/test"
exclude_args=''
if [ ! -z "$exclude" ]; then
exclude_args="$(parse_exclude_paths "$exclude")"
fi
如果通过SSH发送命令没有问题,排除路径将从gzip中排除
ssh root@$host 'cd '"$base"' && tar -zcvf $file '"$base/$target $exclude_args"
答案 0 :(得分:0)
I snooped your question history and saw that you're familiar with PHP. Here's the equivalent problem in PHP:
function foo($arg1, $arg2) {
echo "You passed $arg1 and $arg2\n";
}
$var='"one", "two"';
echo "Running: foo($var);\n";
foo($var);
The echo prints
Running: foo("one", "two");
and that command works just fine if you copy-paste it!Why does
foo($var);
instead writePHP Warning: Missing argument 2 for foo()
?
The answer is of course that literal quotes in your variables don't matter for how the function is called. This is the same in both PHP and shell.
The solution in both PHP and Bash is to use an array:
#!/bin/bash
file="www_2017-04-24.tar.gz"
base="/var"
target="www"
exclude_args=( --exclude '/var/www/bak/*/*' )
cd "$base" && tar -zcvf "$file" "$base/$target" "${exclude_args[@]}"
sh
is more primitive and doesn't support arbitrary arrays, but we can reuse the positional parameters to the same effect:
#!/bin/sh
file="www_2017-04-24.tar.gz"
base="/var"
target="www"
set -- --exclude '/var/www/bak/*/*' # Now assigned to $1, $2, etc
cd "$base" && tar -zcvf "$file" "$base/$target" "$@"
Another option is to use eval
to re-interpret a string as a shell command. This means that anyone who can influence your variables can take over your system, but that may be ok if all the variables come from users with equivalent privileges:
eval "tar -zcvf $file $base/$target $exclude_args"