次のコマンドを実行したいと思います。
tar --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api
ただし、macOSには次の代替措置が必要です。
gtar --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api
(注:パラメータは同じです。)
gtar
最初に呼び出してからtar
フォールバックで、1行でパラメータを一度だけ書き込むことができますか?
答え1
まず、gtarを呼び出してから、代替手段としてtarを1行で呼び出して、パラメータを一度だけ書くことはできますか?
この質問に答えるには:これは、パラメータを配列に格納する簡単な実装で行うことができます。 (Bash / ksh / zsh。参照変数に保存されたコマンドをどのように実行できますか?問題とPOSIX互換の回避策について学びます。 )
args=(--sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api)
if ! tar "${args[@]}"; then
echo "using 'tar' failed, retrying with 'gtar'" >&1
gtar "${args[@]}"
fi
または、次のように主張する場合は、1行で:
tar "${args[@]}" || gtar "${args[@]}"
これは説明できませんが、なぜ問題がアクセスできないディレクトリに似ていても、失敗して別のtarで再試行します。
別のオプションは、最初のコマンドで「コマンドが見つかりません」エラーが発生した場合にコマンドを再実行することです。$?
この場合、シェルは通常127に設定されます。もちろん、これはおそらく何らかの形で存在するので、gtar
最初に反転する必要があります。tar
gtar "${args[@]}"
ret=$?
if [ "$ret" = 127 ]; then
tar "${args[@]}"
ret=$?
fi
テストでは[ "$? = 127 ]
値が削除されるため、$?
実際の終了状態を維持するには追加の変数が必要です。
2つのタールがある特別な場合には、コサロナンダの答えあらかじめ確認してみるのも良い解決策だ。
答え2
tar
macOS で Homebrew インストーラを使用して GNU をインストールした場合、gnu-tar
端末に次のメッセージが表示されます。
GNU "tar" has been installed as "gtar".
If you need to use it as "tar", you can add a "gnubin" directory
to your PATH from your bashrc like:
PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
つまり、上記のインストールメッセージのように最初にtar
設定すると、質問の先頭のコマンドが期待どおりに機能することを意味します。PATH
gnu-tar
PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
tar --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api
条件付き更新PATH
:
if [ "$(uname)" = Darwin ]; then
PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
fi
tar --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api
以下を使用してテストすることもできますcommand -v
。
if command -v gtar >/dev/null 2>&1; then
tar=gtar
elif command -v tar >/dev/null 2>&1 && tar --version | grep -q -F GNU 2>/dev/null; then
tar=tar
else
echo 'No GNU tar available' >&2
exit 1
fi
"$tar" --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api
gtar
コマンドとして存在するかどうかをテストします。その場合、変数はtar
文字列に設定されますgtar
。存在しない場合はテストし、tar
存在する場合は部分文字列を含む項目が返されるかどうかをtar
テストし、その文字列を変数に割り当てます。ただし、テストが失敗した場合は診断メッセージで終了します。tar --version
GNU
tar
tar
後でエラーメッセージで終了しない場合は、"$tar"
asコマンドを使用してください。
uname
明らかに、次の出力をテストすることもできます。
if [ "$(uname)" = Darwin ]; then
# Assumes GNU tar is gtar on macOS and that it's available
tar=gtar
else
# Assumes GNU tar is tar on this system, and that it's available
tar=tar
fi
"$tar" --sort=name --owner=root:0 --group=root:0 --mtime='UTC 2020-01-01' -cvf api.tar api