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:
ksh93
zsh
bash
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
使用できます。bash
type -a
追加資料:
答え2
テキストを処理するためにシェルループを使用しないでください。
代わりにawk
、tr
または、でも使用してくださいsed
。
printf %s\\n "$PATH" | tr ':' '\n'
printf %s "$PATH" | awk 'BEGIN {RS=":"}; 1'
または処理中のシェル変数なので、bash
パターン置換を使用してください。
echo "${PATH//:/
}"
(望むよりLESS=+/parameter/pattern man bash
。)
答え3
pure bash
、これは次のように関連しています。ワイルドカード2番目の方法しかし、これは一行です。
echo -e "${PATH//:/"\n"}"
答え4
シェルユーティリティ:
echo $PATH | tr ':' '\n'