Bash のオートコンプリートは ls とは異なるファイル名を返します

Bash のオートコンプリートは ls とは異なるファイル名を返します

信じられないくらい奇妙なことが起こりました。重大なタイプミスにより、

cp filename.xsl .^?~

そうです、ドット・キャレット・疑問符・チルダです!真実はフィクションよりも奇なり。

さらに奇妙になってきました。

cat .

そして、ヒットするとTAB

./    ../    .^?~

しかし、私が をするとls -a

.    ..    .?~

最後に、私が

rm .?~

削除コマンドは次のようにプロンプ​​トを表示します:

rm: remove write-protected regular file `.\177~'?

正常に削除される前に。キャレットの存在が矛盾するのはなぜですか?

答え1

これは、キャレットがctrlキーが押されたことを示すために、または制御文字であることを示すためによく使用されるためです。

実際に入力したキーシーケンスは次のとおりです。

cp filename.xsl .ctrl+Vbackspace~Enter

おそらく、ファイルをホーム ディレクトリ ( ) にコピーしようとしていたのでしょう。 +~と入力すると、これを繰り返すことができます。画面に が表示されます。ctrlVbackspace^?

印刷されない文字を変換したファイルを表示できますCスタイル次のようにエスケープします (重要なのはフラグです-bが、ファイルがドットで始まるため、-a以下も必要です:

$ ls -ab
.  ..  .\177~

がない場合、-bとしか表示されません。これは、.?~が単に省略されているからではなく^、印刷できない文字が と表示されるからです?touchctrl+ を試してVEnterfooEnterから を試してくださいls。表示されるファイルは になります?foo。次にls -bが表示されます\rfoo

rm .?~この場合、?入力した内容は、シェルによって、実際の疑問符ではなく、任意の 1 文字に一致するグロブ ワイルドカードとして解釈されるため、一致します。エイリアスを付けたので、アクションrmrm -i確認され、それが行われると、C スタイルのエスケープ コードが表示されます。

答え2

ファイル名に含まれている奇妙な文字 ( で示されているようにrm) は、文字0177( 0x7Fh / 127d ) です。それがDel文字です。

Bash の自動補完では、これを一貫して処理できないようです。 印刷できない文字に対してlsは が出力されます?(デフォルト)。次を試してください:

$ echo a > .$'\x7f'~
$ ls -b .??
.\177~

rm役に立ち、その 8 進値を出力します。

答え3

TAB キーを押すと、シェルが何らかのファイル名の推測を行い、8 進数 177 のバイト値を表す 2 つの文字「^」と「?」を出力します。テストとして、Ctrl + V を押してから Shift + Ctrl + ? (一度に 3 つのキー) を押すと、その値のバイトを含むファイル名を取得できます。

ファイル名はドット、キャレット、疑問符、チルダではなく、ドット、8 進数 177、チルダでした。プログラムによって、8 進数 177 のバイトを表す方法が異なります。

関連情報