Meu script de shell (veja abaixo) está falhando no meio da execução com "/bin/sh: 1: Erro de sintaxe: Número fd inválido". Este tópico sugere que o problema está usando a construção >& em sh, que no Ubuntu está vinculada ao dash, que não suporta >&. Estou confuso porque, embora a mensagem de erro sugira que meu script está sendo executado em sh, estou bastante confiante de que ele está sendo executado em bash:
- O shell de login a partir do qual estou executando é o bash, conforme indicado por echo $0.
- A primeira linha do script é #!/bin/bash
- Se eu inserir readlink /proc/$$/exe em meu script (como sugerido aqui ), a saída será /usr/bin/bash.
- Tanto /bin/bash quanto /usr/bin/bash são executáveis reais, não links para outros arquivos.
Então, se estou errado e ele está realmente rodando em sh, por que está acontecendo isso? E se ele está realmente rodando no bash, por que está retornando um erro quando essa sintaxe deveria funcionar no bash?
Estou executando isso no Ubuntu 22.04 usando um kernel 6.5.0-28.
Qualquer feedback é apreciado.
O objetivo deste script é criar um tar multipart (usando este método ) a partir de uma lista de arquivos e diretórios em um arquivo de texto, limitando o tamanho da parte em 512 Gb. Isso deve gerar quatro arquivos, mas falha consistentemente após a terceira parte:
#!/bin/bash
tar -cvf /home/me/archive.tar --multi-volume --tape-length=512000 --new-volume-script='echo -n "/home/me/archive-${TAR_VOLUME}.tar" >&${TAR_FD}' --exclude-tag-all=donotcopy --exclude-backups -T /home/me/file-list.txt
O texto completo do erro na falha é:
bin/sh: 1: Syntax error: Bad fd number
tar: ‘echo -n "/home/me/archive-${TAR_VOLUME}.tar" >&${TAR_FD}’ command failed
tar: Error is not recoverable: exiting now
O formato de file-list.txt é o seguinte:
/home/me/foo
/home/me/bar/file-1.xyz
/home/me/bar/file-2.xyz
O
tar
comando usa/bin/sh
para executar a linha de comando fornecida a--new-volume-script
.Evidência?
Exemplo de saída mostrando claramente que o PID 25662 é executado com
/bin/sh
:Tendo estabelecido que
tar
invocash
, e quesh
muitas vezes é implementado pordash
em vez debash
, podemos passar para informações sobre o número do descritor de arquivo:A saída resultante é
E falha
E falha
Empiricamente, podemos sugerir que um descritor de arquivo de dois dígitos está causando o problema. A leitura
man dash
nos leva até aqui:Em outras palavras, um descritor de arquivo
dash
deve estar no intervalo de 0 a 9, e os descritores de arquivo 10 e superiores não podem ser referenciados por número.A solução aqui é entrar
dash
em um shell com mais flexibilidade, comobash
(dividi o comando em várias linhas para melhorar a legibilidade):