スクリプト内の文字列のシェル独立エスケープ

スクリプト内の文字列のシェル独立エスケープ

私はこれのために(再び)困難を経験しています。

# only in bash
NORM=$'\033[0m'
NORM=$'\e[0m'

# only in dash
NORM='\033[0m'

# only in bash and busybox
NORM=$(echo -en '\033[0m')

echo目的は、出力の使用だけでなく、CLIツールなどのパイプ用の文字列に特殊文字を含めることです。

上記の特定のユースケースでは、を使用するのが$(tput ...)おそらく最善のアプローチです。ただし、外部ツールの要件は最小限に抑えられ、互換性は最大化する一般的なエスケープソリューションが必要です。

通常[ -z "$BASH_VERSION" ]「but」のような条件文を使って助けます。

  1. ビジボックスを検出する簡単な方法が見つかりませんでした。
  2. 5行目の一般変数の割り当て(if / else / fiを使用)はやや過度に見えます。
  3. 私は簡単な解決策を好む

ベストアンサー1

あなたが望むものです"$(printf ...)"。スティーブンは素晴らしい暴露を書いた。printfそしてecho、単純な答えというよりは記事に近いのでここでは全体の内容を繰り返さないでしょう。懸案に関連する基調講演は次のとおりです。

  1. ~によるとPOSIX機能そして携帯性はとても良いです
  2. これは通常シェル組み込みであり、この場合は外部呼び出しや依存関係はありません。

echoまた、慣れて複雑になるとecho思ったので、切り替えに長い時間(例、ほんの数週間)かかったと付け加えるでしょう。printf(このすべてのフラグは何についてのものですか?)実際には非常に単純で、%最後に改行文字を含む固定テキスト以外のprintf操作にはもう気にしません。echo


Printfが簡単になりました

多くのオプションがありますprintf。特定の小数点以下の桁まで数字を印刷できます。それぞれ指定された固定幅(または最小または最大幅)を持つ複数のフィールドを印刷できます。文字シーケンスを含むシェル文字列変数を作成する\tか、\nこれらの文字シーケンスを印刷用のタブと改行として解釈できます。

これらすべてを行うことができ、必要なときに閲覧できるように可能であることを知る必要がありますが、ほとんどの場合、知っておくべきことは次のとおりです。

printf最初の引数として「format」という文字列を使用します。フォーマット文字列は、追加のパラメータを処理する方法(フォーマット方法など)を指定できます。他のパラメータ(形式パラメータ*でまったく引用されていない場合)は次のとおりです。無視される

英数字(およびその他の文字)を型パラメータに含めることで、そのまま印刷できます。バラよりlikeはprintf同じことをしますecho -nが、未知の理由で最初の引数を除くすべての引数を無視します。しかし、実際にはそうではありません。

たとえば、printf some test textこの例では、trysomeは実際には次のように処理されます。滞在printfそして、これには特別な内容が含まれておらず、残りの引数で何をすべきかを知らせないので、その引数は無視され印刷されるのはすべてですsome

%printf後続のパラメータに含まれるデータ型を指定するには、フォーマット文字列(の最初のパラメータ)と特定の文字が必要です。%s「文字列」を意味し、最もよく使用されます。

\nまたは、\tそれぞれの形式に応じて改行とタブに変換します。

これが実際に効率的に使用するために必要なすべてですprintf。非常に簡単ないくつかの例については、次のコードブロックを参照してください。

$ var1="First"
$ var2="Second"
$ var3="Third"
$ printf "$var1" "$var2" "$var3"       # WRONG
First$                                 # Only the first arg is printed, without a trailing newline
$
$ printf '%s\n' "$var1"                # %s means that the next arg will be formatted as a literal string with any special characters printed exactly as-is.
First
$
$ printf '%s' "$var1" "$var2" "$var3"  # When more args are included than the format calls for, the format string is reused.  This example is equivalent to using '%s%s%s' as the format.
FirstSecondThird$                      # All three args were printed; no trailing newline.
$
$ printf '%s\t%s\t%s\n' "$var1" "$var2" "$var3"
First   Second  Third                  # Tab separation with trailing newline.  This format is very explicit about what to do with three arguments.  Now see what happens if four are used:
$ var4="Fourth"
$ printf '%s\t%s\t%s\n' "$var1" "$var2" "$var3" "$var4"
First   Second  Third             # The specified format is reused after the three expected args,
Fourth                            # so this line has two trailing tabs.
$
$ printf '%s\n' "$var1" "$var2" "$var3"  # This format reuse can be used to advantage in printing a list, for example.
First
Second
Third
$
$ printf '%s\t' "$var1" "$var2" "$var3" ; printf '\n'  # Here is a dual command that could have args added without changing the format string...
First   Second  Third   
$ printf '%s\t' "$var1" "$var2" "$var3" "$var4" ; printf '\n'
First   Second  Third   Fourth              # ...as you can see here.
$                                           # It does print a trailing tab before the newline, however.

*もちろん、単一の引数書式指定子シーケンス(たとえば)を含む場合、書式文字列全体%sは、指定されたすべての引数を処理するために必要なだけ再利用されます。例をご覧ください。

おすすめ記事