検索ツールを使用してシステムパス($ PATH)でファイルを検索するには?あるいは、検索の開始点ディレクトリを式としてどのように指定できますか?

検索ツールを使用してシステムパス($ PATH)でファイルを検索するには?あるいは、検索の開始点ディレクトリを式としてどのように指定できますか?

たとえば、システム$ 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というディレクトリのサブディレクトリにのみ実行可能ファイルを見つけることができます。~/binbin~mkdir -p '~/bin'

それは~/bin偽なので削除する必要があります。

実行する場合:

PATH=~/bin:$PATH

参照がない場合は、出力を見つけること~ができます。printf '%s\n' "$PATH"

/home/you/bin:~/bin:/home/samokat/.local/bin:/home/samokat/bin:...

これはホームディレクトリ~/binに適切に拡張され、その後に既に存在する偽のファイルと。bin~/binPATH

しかしyou、実際に仮定すると、samokatこれはディレクトリが2回表示され、$PATHそのうちの1つが重複していることを意味します。

すべてのディレクトリコンポーネントのファイルを$PATH変更したら、必要なものがすべて揃っています。find$PATHbash

(IFS=:; set -o noglob; find -H $PATH -lname /opt/openoffice4/program/soffice)

特殊パラメータは、$IFS引用符なしのパラメータ拡張がどのように分割されるかを決定します。$IFSデフォルトでは、空白文字(改行とタブを含む)が含まれているため、s変更が機能する理由を説明してい:ますが、正しい値に設定することをお勧めします。IFSまた、set -o noglob無効にすることに注意してください。その他引用されていないパラメータ拡張の副作用。

また、-Hこれがないと、find実際にはディレクトリシンボリックリンクであるディレクトリは表示されません。

または、配列バインディングに切り替えることができる場合zsh(たとえば、in)は次のようになります。$PATH$pathcsh

find -H $path -lname /opt/openoffice4/program/soffice

では、zsh代わりにglobを使用することもできますfind

たとえば、

print -rC1 -- $^path/*(N@e['[[ $REPLY:P = /opt/openoffice4/program/soffice ]]'])

print rolumnの実際のエントリは、各コンポーネント内の1 Cシンボリックリンク()パスになります。@$pathP/opt/openoffice4/program/soffice

関連情報