私はスクリプトで作業しており、tar
コマンドを動的に構築する必要があります。
ここに私が何をしようとしているのかを説明する2つの例があります:
#!/bin/bash
TAR_ME="/tmp"
EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
_tar="tar "`printf -- '--exclude="%s" ' "${EXCLUDE[@]}"`" -zcf tmp.tar.gz"
echo COMMAND: "${_tar}"
${_tar} "$TAR_ME"
echo -e "\n\nNEXT:\n\n"
EXCLUDE=("--exclude=/tmp/hello\ hello" "--exclude=/tmp/systemd*" "--exclude=/tmp/Temp*")
_tar="tar "`printf -- '%s ' "${EXCLUDE[@]}"`" -zcf test.tar.gz"
echo COMMAND: "${_tar}"
${_tar} "$TAR_ME"
使えるようにしたい_tar
コマンドとして、クラシックパスで機能させることができましたが、フォルダ名のスペースで機能させる必要があります。そして、毎回次のようなエラーが発生しました:
COMMAND: tar --exclude="/tmp/hello hello" --exclude="/tmp/systemd*" --exclude="/tmp/Temp*" -zcf tmp.tar.gz /tmp
tar: hello": Cannot stat: No such file or directory
COMMAND: tar --exclude=/tmp/hello\ hello --exclude=/tmp/systemd* --exclude=/tmp/Temp* -zcf test.tar.gz
tar: hello: Cannot stat: No such file or directory
知っておくべきことの1つだけですが、非常に古いマシンでスクリプトを実行する必要があります。つまり、最後のbash機能を使用できません。
実行可能な文字列を作成しようとしないでください。代わりに、配列で引数を作成し、tar
を呼び出すときにそれを使用します(EXCLUDE
にはすでに配列を適切に使用しています)。
#!/bin/bash
directory=/tmp
exclude=( "hello hello" "systemd*" "Temp*" )
# Now build the list of "--exclude" options from the exclude array:
for elem in "${exclude[@]}"; do
exclude_opts+=( --exclude="$directory/$elem" )
done
# Run tar
tar -cz -f tmp.tar.gz "${exclude_opts[@]}" "$directory"
/bin/sh
の場合:
#!/bin/sh
directory=/tmp
set -- "hello hello" "systemd*" "Temp*"
# Now build the list of "--exclude" options from the $@ array
# (overwriting the values in $@ while doing so)
for elem do
set -- "$@" --exclude="$directory/$elem"
shift
done
# Run tar
tar -cz -f tmp.tar.gz "$@" "$directory"
sh
コードでの$@
の引用と、bash
コードでの${exclude[@]}
と${exclude_opts[@]}
の引用に注意してください。これにより、リストが個別に引用された要素に展開されます。
関連:
mix(){
p=$1; shift; q=$1; shift; c=
i=1; for a; do c="$c $q \"\${$i}\""; i=$((i+1)); done
eval "${p%\%*}$c${p#*\%}"
}
mix 'tar % -zcf tmp.tar.gz' --exclude "/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*"
EXCLUDE=("/tmp/hello hello" "/tmp/systemd*" "/tmp/Temp*")
mix 'tar % -zcf tmp.tar.gz' --exclude "${EXCLUDE[@]}"
答えを拡張する ここ 。これはバシズムに依存せず、debianの/bin/sh
およびbusybox
でも正常に機能します。