Tenho o seguinte script:
installRequiredFiles=$1
install_with_pkg()
{
arg1=$1
echo $arg1
echo "[+] Running update: $arg1 update."
}
if [ $installRequiredFiles = "true" ]; then
if [ -x "$(command -v apt)" ]; then
install_with_pkg "apt"
elif [ -x "$(command -v yum)" ]; then
install_with_pkg "yum"
elif [ -x "$(command -v apk)" ]; then
install_with_pkg "apk"
else
echo "[!] Can't install files."
fi
fi
Quando executo direto, funciona bem:
root@ubuntu:/# ./myscript.sh "true"
apt
[+] Running update: apt update.
Printing installRequiredFiles: true
Printing arg1: apt
Mas quando estou usando sh -c
estou recebendo o seguinte erro:
root@ubuntu:/# sh -c ./myscript.sh "true"
./c.sh: 11: [: =: unexpected operator
Printing installRequiredFiles:
Printing arg1:
Eu quero ser capaz de executá-lo corretamente sh -c
e quero que ele suporte sh
e bash
que atualmente o faz.
Não
-c
é para isso que serve a opção. Você normalmente não fornece um arquivo, você fornece comandos shell. Ele serve para fazer coisas assim:Agora que você deu um arquivo, ele está tentando lê-lo e executar os comandos encontrados nele, mas o argumento não é passado para o script (
myscript.sh
), o argumento é dado apenas para osh
próprio comando como você pode ver se você basta imprimir os argumentos:Tudo o que você precisa fazer é não usar
-c
e funcionará como esperado:Ou, se você absolutamente precisar usar
-c
por algum motivo, passe o script e o argumento para o script como um único argumento entre aspas parash
:O erro que você obtém é do
dash
shell (o shell usado para implementação/bin/sh
em seu sistema). É por$installRequiredFiles
serComo a variável está vazia, usá-la sem aspas a remove completamente do comando, o que significa que a linha
seria interpretado como
que por sua vez é um erro no uso do
[
comando; ele vê o operador=
quando nenhum operador era esperado.Então, por que
$installRequiredFiles
(e$1
), vazio?O comando
executa o comando
./myscript.sh
com$0
set para a stringtrue
no script. O valor em$0
geralmente é o nome do script ou do shell, e o valor é mais comumente usado em mensagens de diagnóstico (por exemplo, em mensagens de erro que o shell produz).se você tivesse usado
em vez disso, then
$1
teria sido definidotest
como esperado e$0
teria sido definido comosh
(o que é habitual parash -c
scripts in-line). Em ambos os casos, o script teria sido executado por qualquer shell que executasse scripts sem#!
-line. Qual shell acaba executando o script possivelmente depende dosh
shell em sua máquina e pode não sersh
oubash
. Veja, por exemplo, Qual interpretador de shell executa um script sem shebang? .Você provavelmente deseja adicionar uma
#!
linha em seu script apontando para/bin/sh
:Isso significa que você poderá executar seu script assim:
ou, com o equivalente
ou,
Observe que nos dois últimos casos, não é o
sh -c
shell que está executando o script, mas o shell ao qual a#!
linha - no script se refere, como se você executasse./myscript.sh "test"
diretamente. A diferença em relação a antes de adicionar a#!
linha - é que agora você sabe com certeza que este é/bin/sh
e não algum outro shell.O script usa apenas a sintaxe de shell POSIX, o que significa que seria executável por
/bin/sh
, independentemente de qual shell é usado para implementar/bin/sh
em qualquer sistema. Se/bin/sh
isbash
,ksh
oudash
ou algum outro shell mais exótico não importa, o usuário não precisa se preocupar em executar o script com o interpretador correto.Relacionado a várias partes desta resposta: