Script não funciona quando chamado externamente

8

Eu uso um script simples para criar .mp3s a partir de arquivos .mp4:

#!/bin/bash
for i in *.mp4
do
ffmpeg -i "$i" -ab 128k "${i%mp4}mp3"
done

O script funciona bem quando executado na área de trabalho ou chamado através do terminal. Quando o script é chamado de um script externo, no entanto, ele falha na execução, retornando

"* .mp4: Esse arquivo ou diretório não existe".

Eu suspeito que o problema esteja relacionado à expansão do shell, mas não consigo entender como corrigi-lo nessa situação.

M. Street
fonte

Respostas:

13

Você está usando um caminho relativo, em que seu script está procurando os .mp4arquivos no diretório atual, ou seja, o diretório de onde o script está sendo executado e, constatando que esse .mp4arquivo não existe, ele procura um *.mp4arquivo literal (assumindo nullglob/ failglobnão definido, que é o padrão) e esse arquivo também não existe, daí a mensagem de erro *.mp4: No Such File or Directory.

Você deve usar o caminho absoluto:

for i in /directory/*.mp4; do ...; done

Substitua /directory/pelo caminho do diretório real; se você quiser, pode usar o nome do diretório como primeiro argumento:

for i in "$1"/*.mp4; do ...; done

Você pode usar o caminho absoluto ou relativo aqui, mas novamente o caminho absoluto é sempre a opção mais segura.

Agora chame o script executável da maneira usual:

/path/to/script.sh /directory

No diretório de scripts:

./script.sh /directory
heemail
fonte
Obrigado pela ajuda. Estava prestes a lhe dizer que eu já havia tentado isso sem sucesso, mas então notei que havia capitalizado o "H" em "/ casa" pela primeira vez. A passagem do caminho como argumento foi particularmente útil. Felicidades.
M. Street
Onde "daí a mensagem de erro" realmente significa: como o shell não consegue corresponder *.mp4a nenhum arquivo, ele é considerado um nome de arquivo literal e tenta abrir o arquivo chamado *.mp4(que é um nome de arquivo válido) e falha porque você não possui nenhum arquivo. chamado *.mp4no diretório atual. Alguém poderia pensar que *.mp4sempre se expandirá para a lista de nomes de arquivos correspondentes, que poderiam estar vazios (e nesse caso o forloop não faria nada, mas nenhum erro seria gerado), esse não é o caso: *.mp4sempre se expande para algo.
Bakuriu 5/17
@Bakuriu Considerando que isso é verdade neste caso (ou padrão bash), mas nem sempre; olhe para nullglob/ failglob.
precisa saber é
Se eu errei, estava pensando que o '*' era apenas para o nome do arquivo, em vez da combinação de caminho E nome do arquivo. viva e aprenda :)
M. Street