ループ変数の出力が予想値と異なる値を表示します。

ループ変数の出力が予想値と異なる値を表示します。

back/現在の作業ディレクトリにWarという2つのフォルダがあるとしますfront/。私は彼らのそれぞれの中に入り、何かをしようとしました。以下の簡単なスクリプトで:

for dir in */ ; do
    echo "$(dir)"
done

私は次の結果を期待しています:

back
front

しかし、私が得るものは次のとおりです。

back  front
back  front

私は理解できません。結果はcdフォルダに入ろうとすると次のようになります。

for dir in */ ; do
    echo "$(dir)"
    cd $(dir)
    echo "$(pwd)"
    cd ..
done

私は得る:

back  front
/path/to/back
back  front
/path/to/back

つまり、私は決して入らないfront/。誰かが私が間違っていることを理解するのに役立ちますか?

答え1

POSIXに似たシェルでは、構文$(cmd)は次のとおりです。コマンドの置き換え$(cmd)、末尾の改行を引いた出力に展開されます。cmd

あなたが望むものパラメータ拡張$dirまたは${dir}(ここでパラメータはdir 変える)。

pwdprint working dicory)は、1つの特殊変数の内容を出力するコマンドです。$PWDこの変数自体には現在の作業ディレクトリへのパスが含まれているため、改行$(pwd)で終わらない限り同じ内容に展開されます。$PWD$PWD

だからあなたは以下が欲しい:

for dir in */; do 
  (
    printf '%s\n' "$dir"
    cd -- "$dir" &&
      printf '%s\n' "$PWD"
  )
done

または:

for dir in */; do 
  (
    printf '%s\n' "$dir"
    cd -- "$dir" &&
      pwd
  )
done

また覚えてください

  • echo任意のデータの出力には使用できません。printf代わりに使用してください。
  • 通常、コマンドの終了ステータスを確認する必要があります。ここで確認されていない出力は、最初の操作が失敗した場合に次の操作を実行すると、間違った場所に移動することを意味しcdます。cd ..cd
  • cd後者が常に初期位置に戻ることを保証するわけではないので、サブシェルで実行(使用)する方が良いです(...)(シンボリックリンクが含まれている場合、または一部のパスコンポーネントの名前がギャップから変更されている場合)。cd ..
  • --非オプションが開始されないという保証がない場合-(または一部のコマンドでも問題になる可能性がある場合)、+オプションと非オプションを区別するために使用する必要があります。
  • POSIXに似たシェルでは、パラメータ拡張とコマンド置換(算術拡張を含む)を引用符で囲む必要があります。それ以外の場合、通常は望ましくない暗黙の分割+globが発生します(zshを除く)。

また、bash(およびzshを除く他のPOSIXシェル)では、globがファイルと一致しない限り拡張されません。

したがって、現在の作業ディレクトリに、次の種類で判別できる隠しファイルが含まれていない場合目次*/グローバルパターンは*/空のリストではなく独自に拡張され、ディレクトリにcd入ることができないため、エラーが表示されることがあります*/

では、glob修飾子をzsh使用できます(またはで終わらない)。Nfor dir in */(N); do...for dir in *(N-/); do...$dir/

ksh93から: for dir in ~(N)*/; do...

では、このオプションをグローバルに一時的に設定bashできます。nullglob

shopt -s nullglob
for dir in */; do
  ...
done
shopt -u nullglob

完全性のために、$(var)構文は次のとおりです。マクロMakefile■コマンドで使用される拡張子make

このawk言語では、$フィールドを逆参照する単項演算子であり、単に変数を参照するためにvar使用されます。awkしたがって$(var)or と同じで、第 0フィールド (または 0 の場合は全レコード) に展開されます。$var$ varvarvar

同様のシェルではrc、 と同じ機能$(var)も動作します。これは渡された単一要素のリストなので、通常はを使用しても変数を逆参照します。$var$ var$ 'var'$ ( 'var' )$var$var

TCLで、$(var)キー名が空の配列変数の値に展開しますvar

$ tclsh
% array set {} {foo 1 bar 2}
% puts $(foo)
1

はい、この場合Pリントはあまり意味がありません。 (70年代半ばのUnix V5の)コマンドが最初であるとP推測できます。pwd$PWD論理的POSIXで指定された現在の作業ディレクトリの処理は後で行われました(1980年代初め、kshでは実際にpwdエイリアスでした(例、引用符がありません!)、ドキュメントではresent orking icoryに省略されました)。同じ目的のための(現在のorkingディレクトリ)変数があります。print - $PWD-r$PWDPWDtcsh$cwdcwd

関連情報