O espaço não é permitido em um nome de arquivo?

28

Diz-se que no Unix e Linux em geral, você deve evitar ter espaços em um nome de arquivo de um arquivo (arquivo comum, dir, link, arquivo de dispositivo, ...).

Mas eu faço isso o tempo todo. Para um nome de arquivo com um espaço dentro,

  • No Nautilus, o caractere de espaço é mostrado como um espaço.
  • No terminal Bash, eu uso \ para representar um espaço ou coloque o nome do arquivo entre um par de aspas duplas.
  • nos arquivos de alguns aplicativos (Nautilus, não tenho certeza se o sistema operacional também fará isso), o nome do arquivo é gravado com o espaço substituído por %20 .

Um espaço não é realmente permitido em um nome de arquivo?

Como você usa ou lida com um espaço em um nome de arquivo corretamente?

    
por Tim 02.08.2014 / 16:40

4 respostas

45

Espaços e, na verdade, todos os caracteres, exceto / e NUL, são permitidos em nomes de arquivos. A recomendação para não usar espaços em nomes de arquivos vem do perigo de que eles possam ser mal interpretados por softwares que os apoiam mal. Indiscutivelmente, esse software é buggy. Mas também discutivelmente, linguagens de programação como shell script facilitam escrever softwares que quebram quando apresentados a nomes de arquivos com espaços neles, e esses bugs tendem a falhar porque scripts de shell não são frequentemente testados por seus desenvolvedores usando nomes de arquivos com espaços em eles.

Espaços substituídos por %20 geralmente não são vistos em nomes de arquivos. Isso é usado principalmente para URLs (web). Embora seja verdade que% -codificação de URLs, por vezes, faz o seu caminho em nomes de arquivos, muitas vezes por acidente.

    
por 02.08.2014 / 16:50
15

Espaços são permitidos em nomes de arquivos, como você observou.

Se você olhar a entrada "a maioria dos sistemas de arquivos UNIX" em este gráfico na wikipedia , você notará :

  • Qualquer conjunto de caracteres de 8 bits é permitido. Também podemos incluir o ASCII de 7 bits neste guarda-chuva, pois ele é um subconjunto de vários conjuntos de 8 bits e é sempre implementado usando bytes de 8 bits.

  • Os únicos caracteres proibidos são / e "null". "Nulo" refere-se a um byte zero, mas estes não são permitidos em dados de texto de qualquer maneira.

No entanto , se você fizer algum uso do shell, você pode perceber que existem alguns caracteres que criarão problemas, mais significativamente * , que é um operador POSIX globbing.

Dependendo de como você deseja definir "problemas", você poderia incluir espaços em branco (espaços, tabulações, novas linhas, etc.), pois isso cria a necessidade de citar com "" . Mas isso é inevitável, já que espaços são permitidos, então ...

How do you use or deal with a space in a filename correctly?

Em um contexto de linha de comando / shell, coloque o nome do arquivo entre aspas simples ou duplas (mas observe eles não são os mesmos outros problemas do WRT), ou escape dos espaços com \ , ex .:

> foo my\ file\ with\ spaces\ in\ the\ name
    
por 02.08.2014 / 16:57
2

O motivo é amplamente histórico - DE VOLTA, nas névoas de espaços de tempo não eram permitidos em nomes de arquivos, então os espaços eram usados como separadores de palavra-chave / nome de arquivo. Futuros intérpretes de shell precisavam ser compatíveis reversamente com scripts antigos e, portanto, estamos presos à dor de cabeça que temos hoje.

Desenvolvedores de processos que não precisam lidar muito com humanos podem tornar as coisas muito mais fáceis, removendo completamente os espaços. A Apple faz isso, o conteúdo de / System / Library / CoreServices / contém muito poucos espaços, os programas com espaços são abertos em nome do usuário eWouldLookStrangeIfCamelCased. Caminhos semelhantes unix semelhantes também evitam espaços.

(uma anedota relacionada: em meados dos anos 90, um drone do Windows dizia: "Nomeie uma coisa que você pode fazer no Mac que não posso fazer no Windows" - > "Use 12 caracteres em um nome de arquivo". Silêncio. Espaços também eram possíveis nesses 12 caracteres)

    
por 03.08.2014 / 14:42
1

Então, sim, como é dito muitas vezes em outro lugar, um nome de arquivo pode conter praticamente qualquer caractere. Mas precisa ser dito que um nome do arquivo é não um arquivo. Ele carrega algum peso como um arquivo atributo em que você normalmente precisa de um nome de arquivo para abrir um arquivo, mas o nome do arquivo somente aponta para o arquivo real. É um link, armazenado no diretório que o registrou, ao lado do inode number - que é uma aproximação muito mais próxima de um arquivo real .

Então, você sabe, chame como quiser. O kernel não se importa - todas as referências de arquivo que ele irá tratar irão lidar com números reais de inode de qualquer maneira. O nome do arquivo é uma coisa para o consumo humano - se você quer fazer uma coisa louca, bem, é o seu sistema de arquivos. Aqui, eu vou fazer algumas coisas malucas:

Primeiro, vou criar 20 arquivos e nomeá-los apenas com espaços, cada nome contendo mais um espaço que o anterior:

until [ $((i=$i+1)) -gt 20 ]
do  v=$v' ' && touch ./"$v"
done

Isso é meio engraçado. Veja meu ls :

ls -d ./*
./      ./          ./              ./                  ./                 
./      ./          ./              ./                  ./                  
./      ./          ./              ./                  ./                   
./      ./          ./              ./                  ./     

Agora vou espelhar este diretório:

set -- * ; mkdir ../mirror
ls -i1qdU -- "$@" |
sh -c 'while read inum na
    do  ln -T "$1" ../mirror/$inum
    shift ; done' -- "$@"
ls -d ../mirror/*

Aqui estão os conteúdos de ../mirror/ :

../mirror/423759  ../mirror/423764  ../mirror/423769  ../mirror/423774
../mirror/423760  ../mirror/423765  ../mirror/423770  ../mirror/423775
../mirror/423761  ../mirror/423766  ../mirror/423771  ../mirror/423776
../mirror/423762  ../mirror/423767  ../mirror/423772  ../mirror/423777
../mirror/423763  ../mirror/423768  ../mirror/423773  ../mirror/423778

Ok, mas talvez você esteja perguntando - mas que bom é isso? Como você pode dizer qual é qual? Como você pode ter certeza de que vinculou o número de inode correto ao nome de arquivo correto?

Bem ...

echo "heyhey" >>./'    ' 
tgt=$(ls -id ./'    ')
cat ../mirror/${tgt%% .*} \
    $(ls -1td ../mirror/* | head -n1) 

OUTPUT

heyhey
heyhey

Veja, o número do inode contido em ../mirror/"${tgt%% .*}" e o referenciado por ./' ' referem-se ao mesmo arquivo. Eles descrevem o mesmo arquivo. Eles o nomeiam, mas nada mais. Não há mistério, na verdade, apenas algum inconveniente que você possa causar, mas que acabará tendo pouco ou nenhum efeito na operação do seu sistema de arquivos unix no final.

    
por 04.08.2014 / 08:36

Tags