O preenchimento automático do Bash fornece um nome de arquivo diferente de ls

O preenchimento automático do Bash fornece um nome de arquivo diferente de ls

Uma coisa incrivelmente estranha acabou de acontecer. Através de um erro de digitação grave, entrei

cp filename.xsl .^?~

Sim, isso mesmo, ponto-caret-ponto de interrogação-til! A verdade é mais estranha que a ficção.

Fica mais estranho. Quando eu digito

cat .

e então bateu TAB, eu recebo

./    ../    .^?~

mas quando eu faço um ls -a, eu recebo

.    ..    .?~

Finalmente, quando eu faço

rm .?~

o comando remove me avisa assim:

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

antes de removê-lo com sucesso. Por que a discrepância da existência do sinal de intercalação?

Responder1

É porque o cursor é frequentemente usado para indicar que a ctrltecla foi pressionada ou que é um caractere de controle.

A sequência de teclas que você realmente digitou foi esta:

cp filename.xsl .ctrl+Vbackspace~Enter

Você provavelmente estava tentando copiar o arquivo para seu diretório inicial ( ~). Você pode repetir isso digitando ctrl+ Vbackspace. Você verá ^?impresso na tela.

Você pode visualizar arquivos com caracteres não imprimíveis convertidos paraEstilo Cescapa assim (é o sinalizador que é importante, mas como seu arquivo começa com um ponto, você também -bprecisará de :-a

$ ls -ab
.  ..  .\177~

Sem o -bvocê só vê isso .?~não porque está simplesmente omitindo o ^, mas porque qualquer caractere não-principal é exibido como ?. Tente touchctrl+ VEnterfooEntere então ls. O arquivo que você verá será ?foo. Então ls -bmostrará \rfoo.

Então, quando você rm .?~está combinando, porque neste caso o ?que você digitou é interpretado pelo shell como um curinga global para corresponder a qualquer caractere único, não especificamente a um ponto de interrogação real. Você criou rmum alias rm -ipara confirmar sua ação e, quando isso acontece, mostra o código de escape estilo C.

Responder2

O caractere estranho que você tem nesse nome de arquivo (conforme indicado por rm) é o caractere 0177( 0x7Fh / 127d ). Esse é o Delpersonagem.

O preenchimento automático do Bash parece não conseguir lidar com isso de forma consistente. lsimprime a ?para caracteres não imprimíveis (por padrão). Tentar:

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

rmestá sendo útil e imprime seu valor octal.

Responder3

Quando você pressiona TAB e o shell faz algum tipo de adivinhação do nome do arquivo, ele imprime dois caracteres, '^' e '?' para o byte com valor octal 177. Você pode obter um nome de arquivo com um byte desse valor pressionando ctrl-V e depois shift-ctrl-? (três chaves de uma vez) para teste.

O nome do arquivo não era ponto-caret-questionmark-tilde, mas sim ponto-octal 177-til. Diferentes programas escolheram representar o byte com valor octal-177 de maneiras diferentes.

informação relacionada