Nos meus scripts eu tenho uma função chamada messages
. Eu escrevi no Linux Mint, sem problemas para executá-lo, e quando mudei para uma estação Debian Buster, a função entra em conflito com /usr/bin/messages
.
Eu tenho um script de inicialização que chama o script messages
:
startup_script
# call to messages script
. messages
mensagens
messages() {
# reformat the arguments and return them
}
mais tarde startup_script
messages "This is a message"
O que joga
./startup_script: line 35: .: /usr/bin/messages: cannot execute binary file
messages: could not open mailbox `/path/to/my/script/<string passed to my function>': No such file or directory
Então, recebo vários erros relacionados ao fato de /usr/bin/messages
ser chamado em vez da minha função.
Depois de adicionar type messages "This is a message"
, a saída relevante é:
messages is /usr/bin/messages
Tenho a opção de renomear minha função¹, mas talvez haja uma maneira melhor de lidar com essa situação.
Como digo ao meu script para ignorar os binários do sistema e usar minhas próprias funções?
¹ A função é chamada em vários scripts, muitas vezes, então não é a opção mais fácil apenas alterar o nome.
Responder1
É assim que . file
funciona:
Se
file
não contiver uma <barra>, o shell deverá usar o caminho de pesquisa especificado porPATH
para encontrar o diretório que contém o arquivo.
Esse comportamento éespecificado por POSIX.
Seu primeiro erro é
./startup_script: line 35: .: /usr/bin/messages: cannot execute binary file
É semelhante quando você liga . echo
:
-bash: .: /bin/echo: cannot execute binary file
Você está tentando obter o arquivo binário /usr/bin/messages
. Na verdade, seu arquivo onde a função está definida não tem origem alguma, a função não está definida no script atual. Isso significa que mais tarde messages
ainda significa /usr/bin/messages
, não a função.
A linha relevante deve ser . ./messages
ou . /full/path/to/messages
(ou seja, caminho paraseuarquivo, não para o binário).
Responder2
Interpretando mensagens de erro
Veja o número da linha na mensagem de erro. Dessa forma você saberá em qual linha está o erro. Isso ficou escondido de nós, pois você nos mostrou algumas linhas de um script contendo mais de 35 linhas.
Qual arquivo é executado.
Quando você especifica um arquivo com . file-to-source
ou file-to-run
, os diretórios listados na variável de ambiente $PATH
são pesquisados da esquerda para a direita. O diretório atual não está nesta lista, pois pode ser um risco à segurança ou, pelo menos, causar confusão. Para executar um programa no diretório atual, você deve especificar que ele está no diretório atual. por exemplo, . ./file-to-source
ou ./file-to-run
(não há necessidade de fornecer o caminho completo).
Os Unixes costumavam ter .
no PATH, até que se percebeu que isso era um problema. Por exemplo, coloque um programa chamado ls
no diretório atual. O CMD no Windows da Microsoft ainda está .
implicitamente no PATH
, você não pode removê-lo. É uma das causas do alto mallware neste sistema operacional.
Uma pegadinha
.
refere-se ao diretório de trabalho atual e não ao diretório em que o script está.
Para resolver isso, algo assim pode ser feito.
(
cd "$(dirname "$(readlink -f "$0")")"
script_dir="$(pwd)"
)
script_dir/other_script
Espero que alguém possa vincular a uma solução melhor.