IFS を使用してコロンで区切られたパスのリストからループを読み取る際の Bash

IFS を使用してコロンで区切られたパスのリストからループを読み取る際の Bash

where同様に動作するbash関数を作成しようとしていますtcsh。指定された名前の実行可能ファイルのすべての組み込みtcsh関数where、エイリアス、絶対パスが非表示にPATHなっていても一覧表示されます。

tcsh> where tcsh
/usr/bin/tcsh
/bin/tcsh

その一環として、私はその中にあるすべてを繰り返し見て、$PATH適切な名前の実行可能ファイルがあることを確認したいと思います。

$PATH次のbashフラグメントは、コロンで区切られたパスのリストを繰り返し、各コンポーネントの後に改行文字を印刷するように設計されていますが、すべてのコンテンツの内容全体を1行に印刷するようです。

#!/bin/bash
while IFS=':' read -r line; do
    printf "%s\n" "$line"
done <<< "$PATH"

今の状態では単にbash where印刷./whereしてください。/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

それでは、ループ変数の値がコロンで区切られたパスリストの各セグメントになるようにwhileループを設定するにはどうすればよいですか?

ベストアンサー1

read読み取る行から単語を区切るために使用され、IFSその中に文字が最初に表示されるまで読み取った内容は渡されません。read

IFS=: read -r a b

1行を読み、最初の部分の前にその部分を置き、残りの部分を置きます:$a$b

IFS=: read -r a

行全体(残りの部分)を挿入します$a(行に文字が1つだけ含まれていて、:その行の最後の文字ではない場合)。

最初の項目を読むには(または1つのみ)を:使用できます。read -d:ksh93zshbash

printf %s "$PATH" | while IFS= read -rd: dir || [ -n "$dir" ]; do
  ...
done

(追加の改行を追加するためにasを使用しません<<<)。

あるいは、標準噴射を使用してもよい。

IFS=:; set -o noglob
for dir in $PATH""; do
  ...
done

今、いくつかの警告に注意してください。

  • $PATHのコンポーネントは現在のディレクトリを表します。
  • 空白は$PATH現在のディレクトリを意味します。つまり、$PATH現在のディレクトリのコンポーネントが含まれているため、while read -d:この場合、反復はエラーになります。
  • //file/file一部のシステムではそうでないため、$PATH含まれる場合/はその点に注意が必要です$dir/$file
  • 一つ未設定$PATH は次のことを意味します。基本検索パスを使用するには$ PATHが設定されていますが、空のものとは異なります。

tcshこれで/zshのコマンドと同じ場合は 'をwhere使用できます。bashtype -a

追加資料:

おすすめ記事