GNU/Linux >> Linux の 問題 >  >> Linux

bash 引数で引用符を保持する

引用符は、引数がスクリプトに渡される前に削除されるため、保持するには遅すぎます。できることは、引数を内部コマンドに渡すときにそれらの効果を保持し、印刷用に引用/エスケープされた引数の同等のバージョンを再構築することです.

内部コマンド "[email protected]" に引数を渡すため -- 二重引用符を使用すると、[email protected] は元の単語の区切りを保持します。これは、内部コマンドがスクリプトとまったく同じ引数リストを受け取ることを意味します。

印刷の場合、bash の printf コマンドで %q 形式を使用して、引用符を再構築できます。これは常に元の引用を再構築するとは限りませんが、同等のものを構築することに注意してください。 引用/エスケープされた文字列。たとえば、引数 'uptime ; uname -a' を渡した場合 uptime\ \;\ uname\ -a を出力するかもしれません または "uptime ; uname -a" またはその他の同等のもの (同様の例については、@William Pursell の回答を参照してください)。

これらの使用例は次のとおりです:

printf "Running command:"
printf " %q" innercmd "[email protected]" # note the space before %q -- this inserts spaces between arguments
printf "\n"
innercmd "[email protected]"

ユーザーがコマンドを次のように呼び出した場合:

./script 'foo'

スクリプトに与えられる最初の引数は文字列 foo です 引用符なしで。スクリプトがそれと foo を取得できる他の方法とを区別する方法はありません。 引数として (例:./script $(echo foo) または ./script foo または ./script "foo" または ./script \f\o""''""o )。


ユーザーがおそらく入力したものにできるだけ近い引数リストを出力したい場合:

#!/bin/bash
chars='[ !"#$&()*,;<>?\^`{|}]'
for arg
do
    if [[ $arg == *\'* ]]
    then
        arg=\""$arg"\"
    elif [[ $arg == *$chars* ]]
    then
        arg="'$arg'"
    fi
    allargs+=("$arg")    # ${allargs[@]} is to be used only for printing
done
printf '%s\n' "${allargs[*]}"

完璧ではありません。 ''\''"' のような引数 正当化されるよりも受け入れるのが難しい.


Linux
  1. 前の bash コマンドの引数を思い出すにはどうすればよいですか?

  2. bash エクスポート コマンド

  3. jenkins パイプラインで bash コマンドを実行する

  1. Bashの「評価」コマンド?

  2. コマンドライン引数をBashスクリプトに渡しますか?

  3. 一重引用符と二重引用符の両方を含む bash エイリアス コマンド

  1. docker run へのコマンドライン引数

  2. bash:特殊文字を含むコマンドライン引数を渡す方法

  3. bashで(コマンド引数のように)引用符で文字列を分割する方法は?