A página de manual do bash indica o seguinte para a -c
opção:
-c Se a opção -c estiver presente, os comandos serão lidos a partir do primeiro argumento sem opção command_string. Se houver argumentos após command_string, o primeiro argumento será atribuído a $0 e quaisquer argumentos restantes serão atribuídos aos parâmetros posicionais. A atribuição para $0 define o nome do shell, que é usado em mensagens de aviso e erro.
Do exposto, eu esperaria que o código abaixo fosse equivalente em sua saída:
# or possibly (`bash -c date date +%z`)
$ bash -c date +%z
Wed Oct 18 10:02:47 PM UTC 2023
$ date +%z
+0000
# The first command gives the output of `date` without the format specifier.
No entanto, meu bash (GNU bash, versão 5.2.15) nunca parece avaliar parâmetros posicionais adicionais da linha de comando. Tudo após o primeiro argumento após a -c
opção é descartado silenciosamente. Talvez eu esteja entendendo mal a página de manual.
Como eu passaria vários argumentos para um bash -c
comando como palavras (vetor arg nos bastidores) em vez de uma string ( bash -c "date +%z"
)? Isso é possível?
Contexto
Meu objetivo ao fazer esta pergunta é entender como o bash espera que os parâmetros de comando sejam passados para alimentá-los corretamente no bash por meio de uma execve()
família de funções de outro programa (um shell wrapper).
$0 não é o primeiro argumento, $1 é. Além disso, você precisa usar os argumentos na string de comando.
O argumento para -c precisa ser uma string. O resto serão parâmetros $0, $1, ...
Exemplo:
Saída:
name=a params=b c
O uso de aspas simples é importante aqui. Como não permite que o shell atual preencha valores para $0, $* etc.
Se você quiser obter valores do shell atual, use aspas duplas. Por exemplo:
Saída:
42
Misturar aspas simples e duplas também é possível. Contanto que o argumento após -c permaneça uma string.
Saída:
42 0=bash
(aqui o padrão $0 é bash)