-
A opção
-c
permite que os programas executem comandos. É muito mais fácil de bifurcar e fazerexecl("/bin/sh", "sh", "-c", "date | od -cb && ps > ps.out", NULL);
do que é para garfo, criar um cachimbo, garfo novamente, chame
execl
em cada criança, chamewait
, verifique o status de saída, garfo novamente, chameclose(1)
, abra o arquivo, Certifique-se de que ele esteja aberto no descritor de arquivo1 e faça outroexecl
. Acredito que esta foi a razão pela qual a opção foi criada em primeiro lugar.A função de biblioteca
system()
executa um comando pelo método acima. - Ele fornece uma maneira de obter um comando arbitrariamente complexo
e fazer com que pareça um comando simples.
Isso é útil em programas que executam um comando especificado pelo usuário,
como
find … -exec
ouxargs
. Mas você já sabia disso; foi parte da resposta à sua pergunta, Como especificar um comando composto como um argumento para outro comando? -
Pode ser útil se você estiver executando um shell interativo diferente de bash. Por outro lado, se você está executando o bash, você pode usar esta sintaxe
$ ash -c "command" ︙ $ csh -c "command" ︙ $ dash -c "command" ︙ $ zsh -c "command" ︙
para executar um comando em outro shell como todos esses shells também reconhecem a opção
-c
. Claro que você poderia alcançar o mesmo resultado com$ ash ash$ command ︙ ash$ exit $ csh csh$ command ︙ csh$ exit $ dash dash$ command ︙ dash$ exit $ zsh zsh$ command ︙ zsh$ exit
Eu usei
ash$
, etc., para ilustrar os prompts dos diferentes shells; você provavelmente não conseguiria isso. -
Pode ser útil se você quiser executar um comando em um shell bash "fresco"; por exemplo,
$ ls -lA total 0 -rw-r--r-- 1 gman gman 0 Apr 14 20:16 .file1 -rw-r--r-- 1 gman gman 0 Apr 14 20:16 file2 $ echo * file2 $ shopt -s dotglob $ echo * .file1 file2 $ bash -c "echo *" file2
ou
$ type shift shift is a shell builtin $ alias shift=date $ type shift shift is aliased to ‘date’ $ bash -c "type shift" shift is a shell builtin
-
O que precede é uma simplificação excessiva enganosa. Quando o bash é executado com
-c
, ele é considerado um shell não interativo , e não lê~/.bashrc
, a menos que seja-i
especificado. Então,$ type cp cp is aliased to ‘cp -i’ # Defined in ~/.bashrc $ cp .file1 file2 cp: overwrite ‘file2’? n $ bash -c "cp .file1 file2" # Existing file is overwritten without confirmation! $ bash -c -i "cp .file1 file2" cp: overwrite ‘file2’? n
Você pode usar
-ci
,-i -c
ou-ic
em vez de-c -i
.Isso provavelmente se aplica até certo ponto aos outros shells mencionado no parágrafo 3, a forma longa (ou seja, a segunda forma, que é exatamente a mesma quantidade de digitação) pode ser mais seguro, especialmente se você tiver arquivos de inicialização / configuração configuração para essas conchas.
-
Como Curinga explicado , já que você está executando uma nova árvore de processos (um novo processo shell e, potencialmente, seu (s) processo (s) filho (s)), mudanças no ambiente feitas no subshell não pode afetar o shell pai (diretório atual, valores de variáveis de ambiente, definições de funções, etc.) Portanto, é difícil imaginar um comando interno do shell isso seria útil quando executado por
sh -c
.fg
,bg
ejobs
não podem afetar ou acessar trabalhos em segundo plano iniciado pelo shell pai, nem podewait
esperar por eles.sh -c "exec some_program"
é essencialmente equivalente para apenas executarsome_program
da maneira normal, diretamente do shell interativo.sh -c exit
é uma grande perda de tempo.ulimit
eumask
poderiam alterar as configurações do sistema para o processo filho e, em seguida, sair sem exercê-los.Apenas o único comando interno que seria funcional em um contexto
sh -c
ékill
. Claro, os comandos que só produzem saída (echo
,printf
,pwd
etype
) não são afetados, e, se você escrever um arquivo, isso persistirá. - Claro que você pode usar um builtin em conjunto com
um comando externo; por exemplo.,
sh -c "cd some_directory; some_program"
mas você pode conseguir essencialmente o mesmo efeito com um subshell normal:(cd some_directory; some_program)
que é mais eficiente. O mesmo (ambas as partes) pode ser dito para algo comosh -c "umask 77; some_program"
ouulimit
(oushopt
). E desde que você pode colocar um comando arbitrariamente complexo depois de-c
- até a complexidade de um script de shell completo - Você pode ter a oportunidade de usar qualquer um dos repertórios de builtins; por exemplo,source
,read
,export
,times
,set
eunset
, etc.