たとえば、システム$ PATHの一部であるすべてのディレクトリで特定のバイナリを参照するすべてのシンボリックリンクを探したいとします。すべてのディレクトリを手動で指定すると、これを正常に実行できます。
sudo find ~/bin /home/samokat/.local/bin /home/samokat/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /snap/bin -lname /opt/openoffice4/program/soffice
しかし、 $PATH 拡張でコマンドを使用しようとすると、次のようになります。
sudo find `echo $PATH | tr ':' ' '` -lname /opt/openoffice4/program/soffice
エラーと結果が表示されます。
find: ‘~/bin’: No such file or directory
/usr/bin/soffice.link-to-openoffice-bak
echo $PATH | tr ':' ' '
正しいパスを出力してください。
~/bin /home/samokat/.local/bin /home/samokat/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /snap/bin
以下も機能しません。
sudo find `echo $PATH | tr ':' ' ' | xargs` -lname /opt/openoffice4/program/soffice
sudo find { `echo $PATH | tr ':' ' ' | xargs` } -lname /opt/openoffice4/program/soffice
sudo find eval "echo $PATH | tr ':' ' ' | xargs" -lname /opt/openoffice4/program/soffice
echo $PATH | tr ':' ' ' | xargs | sudo find -lname /opt/openoffice4/program/soffice # runs some long computation
starting point
ディレクトリを計算されたパラメータにどのように渡すことができますかfind
?可能ですか?
答え1
すでにアクセス権があるディレクトリを含める必要があるため、sudo
使用する必要はありません。$PATH
この文字は、~
シェルや他のシェルのホームディレクトリへの組み込みショートカットです。bash
しかし、あなたの例で利用できるほど遅く評価されていません。 (引用された式内でも評価されません。)
を設定するときに$PATH
このようなものを使用するのではなく、PATH=~/bin:$PATH
より明示的な選択肢を使用することを検討してくださいPATH="$HOME/bin:$PATH"
。
一部のコードでは、ディレクトリ名のスペースを処理する$PATH
代替ソリューションは次のとおりです。
( IFS=:; for p in $PATH; do [ -d "$p" ] && find "$p" -maxdepth 1 -lname '/opt/openoffice4/program/soffice'; done )
もっと読みやすく、
(
IFS=:
for p in $PATH
do
[ -d "$p" ] && find "$p" -maxdepth 1 -lname '/opt/openoffice4/program/soffice'
done
)
答え2
リテラル$PATH
を含めると、実行したように、現在の作業ディレクトリ内のliteralというディレクトリのサブディレクトリにのみ実行可能ファイルを見つけることができます。~/bin
bin
~
mkdir -p '~/bin'
それは~/bin
偽なので削除する必要があります。
実行する場合:
PATH=~/bin:$PATH
参照がない場合は、出力を見つけること~
ができます。printf '%s\n' "$PATH"
/home/you/bin:~/bin:/home/samokat/.local/bin:/home/samokat/bin:...
これはホームディレクトリ~/bin
に適切に拡張され、その後に既に存在する偽のファイルと。bin
~/bin
PATH
しかしyou
、実際に仮定すると、samokat
これはディレクトリが2回表示され、$PATH
そのうちの1つが重複していることを意味します。
すべてのディレクトリコンポーネントのファイルを$PATH
変更したら、必要なものがすべて揃っています。find
$PATH
bash
(IFS=:; set -o noglob; find -H $PATH -lname /opt/openoffice4/program/soffice)
特殊パラメータは、$IFS
引用符なしのパラメータ拡張がどのように分割されるかを決定します。$IFS
デフォルトでは、空白文字(改行とタブを含む)が含まれているため、s変更が機能する理由を説明してい:
ますが、正しい値に設定することをお勧めします。
IFS
また、set -o noglob
無効にすることに注意してください。その他引用されていないパラメータ拡張の副作用。
また、-H
これがないと、find
実際にはディレクトリシンボリックリンクであるディレクトリは表示されません。
または、配列バインディングに切り替えることができる場合zsh
(たとえば、in)は次のようになります。$PATH
$path
csh
find -H $path -lname /opt/openoffice4/program/soffice
では、zsh
代わりにglobを使用することもできますfind
。
たとえば、
print -rC1 -- $^path/*(N@e['[[ $REPLY:P = /opt/openoffice4/program/soffice ]]'])
print
r
olumnの実際のエントリは、各コンポーネント内の1
C
シンボリックリンク()パスになります。@
$path
P
/opt/openoffice4/program/soffice