Um comando usado em outro comando

2

Para o comando djvused, existe uma opção:

-e command

Cause djvused to execute the commands specified by the option argument commands. It is advisable to surround the djvused commands by single quotes in order to prevent unwanted shell expansion.

Por exemplo, djvused myfile.djvu -e 'print-pure-txt' .

É bastante incomum para mim que um comando (aqui djvused) possa executar outros comandos (aqui por -e option). Eu queria saber como isso é possível? Esta é uma prática freqüente na interface de linha de comando?

Isto é semelhante ao comando print usado no comando awk?

A única maneira que eu sei para um comando ser usado em outro comando é:

echo 'echo hello'

Obrigado e cumprimentos!

    
por Tim 13.07.2011 / 18:31

3 respostas

4

É bastante comum, alguns programas baseiam seu trabalho exclusivamente nisso.

Alguns dos exemplos mais comuns que vêm à mente são su , sudo e xterm .

su -c 'ls -l /root'
sudo ls -l root
xterm -e 'top -d 10'

É diferente do seu exemplo

echo 'echo hello'

onde as aspas inversas são interpretadas pelo shell, e o programa não executa nada em si.

Observe também a diferença entre su e sudo . O primeiro pega uma string, e pode ser difícil configurar tal string do ponto de vista do usuário, por exemplo, para expandir uma variável antes é vista pelo comando; o segundo é uma série de strings e é muito mais simples (não há citações no exemplo sudo ).

O que eles usam para implementar seu trabalho interno? Existem basicamente duas maneiras: a rotina de biblioteca system e a chamada de sistema exec . O primeiro chama um shell e permite várias expansões de shell, como

su -c 'ls -ld /root/.*'

enquanto o segundo método não permite essa liberdade.

    
por 13.07.2011 / 19:47
2

Backticks são obsoletos, porque dificilmente são encaixáveis e não são facilmente distinguidos em fontes diferentes de apóstrofos.

Em vez disso, use $ (cmd), que é trivial:

echo $(echo $(echo $(echo $(echo $(echo hello)))))

E sim, é um recurso frequentemente desejado, mesmo que raramente seja usado.

Mas os programas, que processam comandos, mas não necessariamente invocam a si mesmos novamente, são legiões:

  • shells como bash, dash, zsh claro
  • todas as linguagens com scripts, como scala, haskell, ruby, python, lua, perl, php, ...
  • mais idiomas específicos, como bc, r, ...
  • interfaces sql como psql -c "SELECT foo FROM bar" sampledb
  • shells remotas como ssh, telnet, ...
por 13.07.2011 / 19:38
1

O mais excelente editor de texto Vim, e seu antecessor, vi, tem esse recurso:

Digite!) date quando seu cursor estiver em uma linha em branco, e a saída do comando date será colocada na linha em branco.

Eu uso essa pequena sequência quando adiciono arquivos cheios de anotações ou listas de tarefas para que eu tenha entradas com registro de data e hora.

Novamente no Vim, você pode colocar o cursor na primeira linha de um parágrafo do texto, pressionar V, usar j para descer uma linha de cada vez até a última linha do parágrafo. Bata! Fmt e obtenha seu texto formatado em menos de 80 linhas de coluna. O Vim destaca a marcação, mas uma variante é um truque comum no vi antigo, que tinha apenas marcas: 'a,' b! Fmt

Quanto a questões mais técnicas, isso pode ser feito de várias maneiras. A chamada da biblioteca padrão C system(3) é uma maneira comum de executar um comman externo. Essa chamada de biblioteca padrão pode impor muitas suposições para o que você deseja fazer, caso em que você usaria a chamada de sistema fork(2) para obter um novo processo, que alteraria os descritores de arquivo ou outras coisas e, em seguida, chamaria execve(2) system chamada para fazer com que o kernel carregue um arquivo executável diferente no espaço de endereço do novo processo.

É uma coisa relativamente comum para um programa de linha de comando, porque permite uma reutilização tão grande de outros comandos.

    
por 14.07.2011 / 01:32