Como saber qual parâmetro está sendo fornecido a um comando com um operador de redirecionamento?

9

Isso funciona:

$ echo "notificar-enviar OLÁ!" | agora

Isto não:

$ at now <echo "notificar-enviar OLÁ!"

Diz 'arquivo ou diretório não encontrado ".

Entendo que existe uma -fopção para esse comando, com o qual posso fornecer o arquivo a ser executado em um determinado momento.

Então isso me fez pensar ... em geral, como sei para qual parâmetro os operadores de redirecionamento fornecem o valor?

vlad-ardelean
fonte
5
Sua pergunta não é muito clara. O que você quer dizer com "qual parâmetro". Seu problema provavelmente é que você (por engano) pensa isso foo | bare bar < fooé equivalente. Eles não são.
terdon

Respostas:

16

Você está usando duas coisas diferentes aqui e deve usar uma terceira. Vamos ver:

  1. |: Este é o operador do tubo , que serve para passar a saída de um processo como entrada para outro:

    foo | bar

    Isso executa o programa fooe passa sua saída como entrada para o programa bar.

  2. >, <, >>E <<: Estes são os operadores de redirecionamento , eles servem para enviar dados de / para arquivos :

    • foo > bar: executa o programa fooe salva sua saída no arquivo bar , substituindo 1 seu conteúdo e criando-o se ele não existir.

    • foo >> bar: executa o programa fooe salva sua saída no arquivo bar , anexando ao seu conteúdo e criando-o se ele não existir.

    • foo < bar: é executado foo, dizendo para ler a entrada do arquivo bar .

    • Esse <<é um caso especial, já que não há sentido em "anexar" a entrada a um comando, ele <<é principalmente (exclusivamente AFAIK) usado para o Here Documents :

      $ cat << EOF > file.txt
      > Hello World!
      > EOF

      A construção << SomeStringHere > Out.fileredirecionará todo o texto escrito até encontrar a sequência final ( EOFno exemplo acima) para o arquivo de destino. Aqui, os documentos permitem formatar facilmente seqüências de várias linhas e incluir variáveis ​​e caracteres especiais.

  3. O <<<operador, a Cadeia de caracteres Here , é como um documento Here, mas expande variáveis. Então, por exemplo:

    grep foo <<< "$bar"

    O comando acima é equivalente a echo "$bar" | grep foo.

  4. O que você está realmente procurando é chamado substituição de processo e é outra maneira de passar a saída de um comando para outro. Consiste em <(command).

    foo <(bar) 

    Então, para o seu atexemplo, você poderia fazer

    at now < <(echo "notify-send HELLO")

    O procedimento acima funciona porque a substituição do processo realmente cria um arquivo (leia o link acima para obter mais detalhes) e é o descritor de arquivo desse arquivo que é passado <para at now.


1 O comportamento padrão é substituir, isso pode ser modificado definindo a noclobberopção bash. Se definido, echo foo > barfalhará se barexistir. Nesse caso, ele pode ser forçado usando echo foo |> bar. Veja a seção 3.6.2 aqui .

Terdon
fonte
11
Boa resposta! muito completo (incluindo especialmente as diferenças entre os redirecionadores de arquivo)
steeldriver
@steeldriver aww, shucks, obrigado :) E assim foi esta sob gem apreciado. Eu gostaria de poder lhe dar um +1 para cada uma das várias armadilhas que sua solução evita silenciosamente.
terdon
Você também pode expandir para incluir algumas informações sobre <<e <<<(que @steeldriver mencionou em sua resposta). Além disso, há mais - algo como >>>>>>ou <<<<<<<<<<?
Aditya
@Aditya done. E não se preocupe, ele pára em <<<:)
terdon
12

Nesse caso, echo "notify-send HELLO"um processo não é um arquivo - portanto, você precisa de uma substituição de processo e não de um redirecionamento de arquivo

at now < <(echo "notify-send HELLO")

Você também pode ter usado uma string here para evitar o echocomando inteiramente

at now <<< "notify-send HELLO"
chave de aço
fonte
5
Tendo visto o tipo de perguntas que você costuma gostar (as mesmas que eu), acho que você deveria dedicar mais tempo ao Unix e Linux . Nós vivemos e morremos para truques shell legal por lá ..
terdon
@terdon: a mesma coisa para golfistas perl?
22414 Sylvain Pineau
11
@SylvainPineau oooh yeah. Muito mesmo :). Sério, o tipo de pergunta que você, chave de aço e eu gostamos, é muito mais comum por lá. O lugar está cheio de geeks da linha de comando, alguns dos quais são absurdamente conhecedores.
terdon