O autocompletar Bash fornece um nome de arquivo diferente de ls

6

Uma coisa incrivelmente estranha aconteceu. Através de um erro grave, eu entrei

cp filename.xsl .^?~

Sim, é isso mesmo, dot-caret-questionmark-tilde! A verdade é mais estranha que a ficção.

Isso fica mais estranho. Quando eu digito

cat .

e depois clica em TAB , eu obtenho

./    ../    .^?~

mas quando faço um ls -a , obtenho

.    ..    .?~

Finalmente, quando faço

rm .?~

o comando remove me avisa assim:

rm: remove write-protected regular file '.7~'?

antes de removê-lo com sucesso. Por que a descriçâo da existência do caret?

    
por Kazark 03.07.2012 / 22:19

3 respostas

11

É porque o cursor é usado frequentemente para indicar que a tecla ctrl foi pressionada ou que, de outra forma, é um caractere de controle.

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

cp filename.xsl . ctrl + V retrocesso ~ Introduzir

Você estava supostamente tentando copiar o arquivo para o seu diretório pessoal ( ~ ). Você pode repetir isto digitando ctrl + V backspace . Você verá ^? impresso na tela.

Você pode visualizar arquivos com caracteres não imprimíveis convertidos em estilo C como este (é o sinal -b importante, mas como o arquivo começa com um ponto, você precisará de -a também:

$ ls -ab
.  ..  .7~

Sem o -b você só o vê como .?~ não porque ele está simplesmente omitindo o ^ , mas porque qualquer caractere não legível é exibido como ? . Tente touch ctrl + V Digite foo Digite e, em seguida, ls . O arquivo que você verá será ?foo . Então ls -b mostrará \rfoo .

Então, quando você rm .?~ está correspondendo, porque nesse caso o ? que você digitou é interpretado pelo shell como um curinga globbing para corresponder a qualquer caractere único, não especificamente um ponto de interrogação real. Você tem rm aliased para rm -i , então está confirmando sua ação e quando isso acontece mostra o código de escape no estilo C.

    
por 03.07.2012 / 22:56
2

O caractere estranho que você tem nesse nome de arquivo (como indicado por rm ) é o caractere 0177 ( 0x7F h / 127 d ). Esse é o caractere Del .

O preenchimento automático do Bash parece não conseguir lidar com ele consistentemente. ls imprime ? para caracteres não imprimíveis (por padrão). Experimente:

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

rm está sendo útil e imprime seu valor octal.

    
por 03.07.2012 / 22:55
2

Quando você pressiona TAB, e o shell faz algum tipo de suposição de nome de arquivo, está imprimindo dois caracteres, '^' e '? para o byte valorizado octal 177. Você pode obter um nome de arquivo com um byte desse valor pressionando ctrl-V e shift-ctrl-? (três chaves ao mesmo tempo) para testes.

O nome do arquivo não era dot-caret-questionmark-til, mas sim ponto-octal 177-til. Diferentes programas escolheram representar os diferentes bytes de valor de octal-177.

    
por 03.07.2012 / 22:56