Linuxプログラムは必要なときにのみファイル名を引用しますか?

Linuxプログラムは必要なときにのみファイル名を引用しますか?

次のディレクトリとファイルを持つことを検討してください。

$ tree /tmp/test
/tmp/test
├── dir
│   ├── file_normal
│   ├── file with "double quote
│   ├── file with 'single quote
│   ├── file with space
│   └── special!char
├── dir with space
│   ├── file_normal
│   ├── file with "double quote
│   ├── file with 'single quote
│   ├── file with space
│   └── special!char
├── file_normal
├── file with "double quote
├── file with 'single quote
├── file with space
└── special!char

ls一重引用符または二重引用符を追加必要なときだけ。引用符dirはありませんfile_normal

$ ls -1 /tmp/test
dir
'dir with space'
file_normal
'file with "double quote'
"file with 'single quote"
'file with space'
'special!char'

ls単一ファイルに対して同じことを行います。

必要でない限り、引用符を追加しないでください。

$ ls "file_normal"
file_normal
$ ( cd dir ; ls "$( realpath file_normal )" )
/tmp/test/dir/file_normal

必要な場合にのみ引用符を追加してください。

$ ls "file with space"
'file with space'
$ ( cd 'dir with space' ; ls "$( realpath file_normal )" )
'/tmp/test/dir with space/file_normal'

lsシェルスクリプトでの使用を検討することは通常お勧めできません。同じ機能を実装する組み込みLinuxプログラムはありますか?必要に応じてファイルパスに一重引用符または二重引用符を追加しますか?

答え1

例: ls。ただ使用してください。すべてのルールと同様に、「lsを使用しないでください」という意味のある例外があります。これはそれらの一つです。まず理解する必要があります。なぜls使用はお勧めできません。

  • これは、単純なシェルグローブがタスクを完全に実行する状況で使用され、シェルが出力を解析せずに個々の単語へのパスを直接提供するlsため、可能な限り優れたタスクを実行することがよくあります。 (特に外観は似ていますが、そうでないことをls見ると迷惑です。)for i in $(ls *.xyz)for i in *.xyz
  • 可変の列サイズのため、追加ls -l情報とファイル名を取得しようとすると解析することは困難です。使用statまたはfind交換してください。
  • ls?出力で特殊文字の処理が難しい場合があります(たとえば、一部の文字が置き換えられます)。

この場合:

  • あなたは明らかにすでに関連パスがあるので、lsglobを十分に得るために誤用しないでください。
  • ls -lパス以外の情報を使用または取得しようとしません。
  • あなた考えるls--quoting-style=shell-escape特別出力提供(具体的に)

したがって、次のように使用してください。

quoted_path=$(ls -d --quoting-style=shell-escape <some-path>)

そうでないことを必ず理解してください。基準。最新バージョンのGNU lsはこれを実行できますが、busybox lsはこれを実行しないため(AFAICT)、すべてのLinuxシステムがそれをサポートしているわけではありません。


また、使用することができますGNU統計同じ場合は、%N書式指定子を使用してください。

  • %N- シンボリックリンクの場合、ファイル名は引用または引用されません(下記参照)。
    [...] " "形式は環境変数を使用して設定できます
    。この環境変数が設定されていない場合、デフォルトは ""です。%NQUOTING_STYLEshell-escape-always

だから:

quoted_path=$(QUOTING_STYLE=shell-escape stat -c %N <some-path>)

forへの参照スタイルはstatforと同じようですls(内部的に同じ機能を使用すると大胆です)。この場合の主な違いはシンボリックリンク処理のようです。statシンボリックリンクをそのまま処理したい場合は、おそらくそれを使用したくないでしょう。

% QUOTING_STYLE=shell-escape stat -c %N bar$'\n'baz$'\t'xyz
'bar'$'\n''baz'$'\t''xyz' -> 'foo bar'
% ls --quoting-style=shell-escape bar$'\n'baz$'\t'xyz
'bar'$'\n''baz'$'\t''xyz'

その他のオプション:

  • Bash パラメータ拡張Q引用符演算子の使用:${foo@Q}変数の内容を引用符で囲んで印刷しますfoo(ただし、常に引用符を追加するようです).
  • Bashprintf書式%q指定子(引用符よりもバックスラッシュを好むようですが、必要でない場合はエスケープを追加しません)

関連情報