O que 'data 2 & $ 0' faz?

6

Estou vendo um código de shell de colegas de trabalho e vi isso:

date 2&>$0

Eu sei qual é a data, mas o que 2 & > $ 0 está fazendo? Ele está fora por um tempo, então eu não posso perguntar a ele sobre o que essa parte era.

    
por j0h 07.01.2015 / 04:27

2 respostas

8

Resumo

Em bash , se esse comando estiver em um script, o arquivo de script será substituído por uma mensagem de erro.

Exemplo

Considere o script:

$ cat test.sh
date 2&>$0

Agora, execute o script:

$ bash test.sh
test.sh: line 2: unexpected EOF while looking for matching '''
test.sh: line 3: syntax error: unexpected end of file

Observe o novo conteúdo do script:

$ cat test.sh
date: invalid date '2'

Explicação

O comando date 2&>$0 é interpretado da seguinte forma:

  1. O comando date é executado com o argumento 2

  2. Toda saída, stdout e stderr, do comando date é redirecionada para o arquivo $0 . $0 é o nome do script atual.

    O símbolo > indica o redirecionamento de, por padrão, stdout. Como uma extensão bash , o símbolo &> é um redirecionamento de indicação de atalho de ambos stdout e stderr. Conseqüentemente, stdout e stderr são redirecionados para o arquivo $0 .

  3. Quando o arquivo de script for sobrescrito, ele não será mais um script válido e bash reclamará dos comandos malformados.

Diferença entre bash e shells POSIX

Com um shell POSIX simples, como dash , o atalho &> não é suportado. Portanto, o comando date 2&>$0 redirecionará o somente stdout para o arquivo $0 . Nesse caso, isso significa que o arquivo de script é sobrescrito com um arquivo vazio, enquanto a mensagem de erro date aparecerá no terminal.

    
por 07.01.2015 / 04:43
10

Assumindo que o código que você postou está correto, o que ele faz é muito estranho. Isso:

  • Executa date 2 , que não é uma invocação válida de date e que produzirá uma mensagem de erro e, em seguida,
  • Redireciona a saída padrão e o erro padrão &> ,
  • No arquivo que contém o script em execução ( $0 ), apagando seus conteúdos existentes.

Porque a forma como o Bash lê o script é pegar uma linha de cada vez do arquivo, o que resulta em um absurdo do arquivo sobrescrito e provavelmente saindo (porque o arquivo foi truncado para um ponto menor que o ponto dessa linha) apareceu) ou dando um erro de sintaxe (se o original foi muito curto e parte do erro é lido como a próxima linha).

Eu não consigo pensar em um único uso legítimo para essa linha, mas como você diz que deu exatamente como está escrito, é isso que faz.

Estritamente falando, é possível dar outro valor a $0 e, assim, executar este código de forma não destrutiva invocando o Bash com a opção -c : bash -c "$(<test.bash)" output-file colocará a mensagem de erro em output-file , mas é totalmente perverso para o fazer.

    
por 07.01.2015 / 04:44