web-dev-qa-db-ja.com

Bashの引用符付き文字列内で環境変数を使用する方法

Bashスクリプトで次のさまざまな形式を試しました。

#!/bin/bash
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

しかし、COLUMNS環境変数を正しく展開する構文を取得できません。

次のさまざまな形式を試しました。

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W $COLUMNS'

そして

svn diff $@ --diff-cmd /usr/bin/diff -x '-y -w -p -W ${COLUMNS}'

そして

eval svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

提案?

80
Jamie

不明な場合は、ターミナルで「cols」リクエストを使用し、COLUMNSを忘れる可能性があります。

COLS=$(tput cols)
15
TheBonsai

(私がそうだったように)タイトルで尋ねられた一般的な質問への答えを探してGoogle経由でここに来た人のための簡単なメモ/要約。引用符内のシェル変数にアクセスするには、次のいずれかが機能するはずです。

echo "$VARIABLE"
echo "${VARIABLE}"

単一引用符の使用が主な問題です。 Bash Reference Manual によると:

文字を一重引用符(')で囲むと、引用符内の各文字のリテラル値が保持されます。バックスラッシュが先行する場合でも、単一引用符の間に単一引用符が発生しない場合があります。 [...]二重引用符(")で文字を囲むと、引用符内のすべての文字のリテラル値が保持されますが、$`\、そして、履歴展開が有効な場合、!。文字$および `は、二重引用符内で特別な意味を保持します(シェル拡張を参照)。バックスラッシュは、$`"\、または改行のいずれかの文字が後に続く場合にのみ、特別な意味を保持します。二重引用符内では、これらの文字のいずれかが後に続くバックスラッシュは削除されます。特別な意味のない文字の前のバックスラッシュは変更されません。二重引用符は、二重引用符の前にバックスラッシュを付けることで引用できます。有効にすると、二重引用符で囲まれた!がバックスラッシュを使用してエスケープされない限り、履歴展開が実行されます。 !の前のバックスラッシュは削除されません。特別なパラメーター*および@は、二重引用符で囲まれている場合に特別な意味を持ちます(シェルパラメーターの拡張を参照)。

質問で尋ねられた特定のケースでは、$ COLUMNSは非標準のプロパティを持つ特別な変数です(上記のlhunathの答えを参照)。

350

COLUMNSは次のとおりです。

  1. ではなく環境変数。これは、bash自体によって設定される通常のbashパラメーターです。
  2. SIGWINCH信号を受信すると自動的に設定されます。

通常、2番目のポイントは、COLUMNS変数がinteractiveシェルでのみ設定されることを意味します。not bashスクリプト。

スクリプトのstdinが端末に接続されている場合、端末に問い合わせることにより、手動で端末の幅を調べることができます。

tput cols

SVNコマンドでこれを使用するには:

svn diff "$@" --diff-cmd /usr/bin/diff -x "-y -w -p -W $(tput cols)"

(注:quote"$@"を使用し、evalに近づかないでください;-))

13
lhunath

次のスクリプトは、$COLUMNSの複数の値に対して機能します。この呼び出しの前にCOLUMNSを設定していないのだろうか?

#!/bin/bash
COLUMNS=30
svn diff $@ --diff-cmd /usr/bin/diff -x "-y -w -p -W $COLUMNS"

スクリプト内で$COLUMNSをエコーし​​て、正しく設定されているかどうかを確認できますか?

1
Alex B

あなたはそれを正しくやっているので、他の何かが間違っていると思います(COLUMNSをエクスポートしていないのですか?)。

これらのケースをデバッグするためのコツは、特殊なコマンド(プログラミング言語のユーザー向けのクロージャー)を作成することです。 diff-columns doingという名前のシェルスクリプトを作成します。

exec /usr/bin/diff -x -y -w -p -W "$COLUMNS" "$@"

そしてただ使用する

svn diff "$@" --diff-cmd  diff-columns

このようにして、コードは読みやすく、よりモジュール化され(トップダウンアプローチ)、diff-columnsコードを個別にテストできます(ボトムアップアプローチ)。

0
Colas Nahaboo