Você está interpretando a página de manual errada. Em primeiro lugar, a parte de --
sinalizar o fim das opções é irrelevante para o que você está tentando fazer. Ele -c
substitui o restante da linha de comando a partir desse ponto, para que ele não passe mais pelo manuseio de opções do bash, o que significa que --
ele seria passado para o comando, não tratado pelo bash como um marcador de fim de opções.
O segundo erro é que argumentos extras são atribuídos como parâmetros posicionais ao processo do shell iniciado, e não passados como argumentos ao comando. Então, o que você está tentando fazer pode ser feito como um dos seguintes:
/bin/bash -c 'echo "$0" "$1"' foo bar
/bin/bash -c 'echo "$@"' bash foo bar
No primeiro caso, passar ecoar os parâmetros $0
e $1
explicitamente, e no segundo caso, usar "$@"
para expandir como normal como "todos os parâmetros posicionais, exceto $ 0". Observe que, nesse caso, temos que passar algo para ser usado $0
também; Eu escolhi "bash", pois é o $0
que normalmente seria, mas qualquer outra coisa funcionaria.
Quanto à razão que é feito desta forma, em vez de apenas passar quaisquer argumentos que dão diretamente para o comando que você listar: nota que a documentação diz "comando s são lidos da cadeia", plural. Em outras palavras, esse esquema permite que você faça:
/bin/bash -c 'mkdir "$1"; cd "$1"; touch "$2"' bash dir file
Porém, observe que uma maneira melhor de atingir seu objetivo original pode ser usar, em env
vez de bash
:
/usr/bin/env -- "ls" "-l"
Se você não precisar de nenhum dos recursos que um shell está fornecendo, não há motivo para usá-lo - env
nesse caso, será mais rápido, mais simples e com menos digitação. E você não precisa pensar muito para garantir que ele manipule com segurança nomes de arquivos contendo metacaracteres de shell ou espaços em branco.