GNU/Linux >> Linux の 問題 >  >> Linux

`find -exec Sh -c`を安全に使用することは可能ですか?

findを使用しようとしています echo 0へ 一部のファイルに追加されますが、これは sh -cでのみ機能するようです。 :

find /proc/sys/net/ipv6 -name accept_ra -exec sh -c 'echo 0 > {}' ;

ただし、 sh -cを使用する find -execを使用 引用の問題が疑われるので、とても不安になります。私はそれを少しいじりました、そして明らかに私の疑いは正当化されました:

  • 私のテスト設定:

    [email protected] ~ % cd findtest 
    [email protected] ~/findtest % echo one > file with spaces
    [email protected] ~/findtest % echo two > file with 'single quotes'
    [email protected] ~/findtest % echo three > file with "double quotes"
    [email protected] ~/findtest % ll
    insgesamt 12K
    -rw-rw-r-- 1 martin martin 6 Sep 17 12:01 file with "double quotes"
    -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with 'single quotes'
    -rw-rw-r-- 1 martin martin 4 Sep 17 12:01 file with spaces
    
  • find -execを使用する sh -cなし 問題なく動作しているようです–ここで引用する必要はありません:

    [email protected] ~ % find findtest -type f -exec cat {} ;
    one
    two
    three
    
  • しかし、 sh -cを使用している場合 {} ある種の引用が必要なようです:

    [email protected] ~ % LANG=C find findtest -type f -exec sh -c 'cat {}' ;
    cat: findtest/file: No such file or directory
    cat: with: No such file or directory
    cat: spaces: No such file or directory
    cat: findtest/file: No such file or directory
    cat: with: No such file or directory
    cat: single quotes: No such file or directory
    cat: findtest/file: No such file or directory
    cat: with: No such file or directory
    cat: double quotes: No such file or directory
    
  • 二重引用符は、ファイル名に二重引用符が含まれていない限り機能します:

    [email protected] ~ % LANG=C find findtest -type f -exec sh -c 'cat "{}"' ;
    one
    two
    cat: findtest/file with double: No such file or directory
    cat: quotes: No such file or directory
    
  • 一重引用符は、ファイル名に一重引用符が含まれていない限り機能します:

    [email protected] ~ % LANG=C find findtest -type f -exec sh -c "cat '{}'" ;
    one
    cat: findtest/file with single: No such file or directory
    cat: quotes: No such file or directory
    three
    

すべての場合に機能する解決策は見つかりませんでした。私が見落としているもの、または sh -cを使用しているものはありますか find -execで 本質的に安全ではありませんか?

承認された回答:

{}を埋め込まないでください シェルコードで!これにより、コマンドインジェクションの脆弱性が発生します。 cat "{}"の場合は注意してください 、それは"だけではありません 文字、 ` $ これも問題です(たとえば、 ./ $(reboot)/ accept_raというファイルを考えてみてください。 )¹。

ここでは、ファイル名を個別の引数として shに渡します。 (コードにはありません 引数)、および sh インラインスクリプト(コード 引数)位置パラメータを使用してそれらを参照するには:

find . -name accept_ra -exec sh -c 'echo 0 > "$1"' sh {} ;

または、1つの shを実行しないようにします ファイルごと:

find . -name accept_ra -exec sh -c 'for file do
  echo 0 > "$file"; done' sh {} +

同じことがxargs-I {}にも当てはまります またはzshzargs-I {} 。書かないでください:

関連:Linux –LinuxはMacの「ShaketoFindCursor」に相当しますか?

<ストライク>

<list.txt xargs -I{} sh -c 'cmd > {}'

これは、 findと同じようにコマンドインジェクションの脆弱性になります 上記、ただし:

<list.txt xargs sh -c 'for file do cmd > "$file"; done' sh

これには、1つの shの実行を回避できるという利点もあります。 ファイルごと、および list.txtの場合のエラー ファイルが含まれていません。

zshを使用 のzargs sh -c を呼び出すのではなく、関数を使用することをお勧めします。 :

do-it() cmd > $1
zargs ./*.txt -- do-it

上記のすべての例で、2番目の sh 上記はインラインスクリプトの$0に入ります 。そこで関連するもの( sh など)を使用する必要があります またはfind-sh )、 _のようなものではありません 、-- または、 $ 0の値としての空の文字列 シェルのエラーメッセージに使用されます:

$ find . -name accept_ra -exec sh -c 'echo 0 > "$1"' inline-sh {} ;
inline-sh: ./accept_ra: Permission denied

GNUパラレル 動作が異なります。それを使用すると、しない sh -cを使用したい parallelとして すでにシェルを実行していて、 {}を置き換えようとします シェルの正しい構文で引用された引数を使用します。

<list.txt PARALLEL_SHELL=sh parallel 'cmd > {}'


Linux
  1. autofsを使用してNFS共有をマウントする方法

  2. LinuxでTarコマンドを使用する方法

  3. Vimでファイルタイプを使用する方法は?

  1. _roffを使用して単語に下線を付けますか?

  2. chmodを使用してファイルのパーミッションを変更するにはどうすればよいですか?

  3. Linux で .dll を使用可能

  1. Linuxでlsの代わりにexaを使用する理由

  2. ファイル名に / を使用できますか?

  3. shm_open を使用する理由