Usando | O caractere pipe de uma variável $ faz com que seja tratado apenas como outro argumento no bash; como escapar disso?

6

Eu tenho um script bash como este

export pipedargument="| sort -n"
ls $pipedargument

Mas dá o erro

ls: |: No such file or directory
ls: sort: No such file or directory

Parece estar tratando o conteúdo de "| sort -n" como apenas um argumento passado para ls .

Como posso escapar para que seja tratado como um comando canalizado regular?

Estou tentando definir condicionalmente o $pipedargument . Eu acho que eu poderia apenas executar condicionalmente diferentes versões do comando, mas ainda me perguntando se há uma maneira de fazer este trabalho como acima?

    
por laggingreflex 01.01.2015 / 03:36

3 respostas

6

Você está certo de que não pode usar | dessa maneira. A razão é que o shell já procurou por pipelines e os separou em comandos antes de fazer a substituição de variáveis. Portanto, | é tratado apenas como outro caractere.

Uma alternativa possível é colocar o caractere de canal literalmente:

$ cmd="sort -n"
$ ls | $cmd

Caso você não queira um pipeline, use cat como "nop" ou espaço reservado:

$ cmd=cat
$ ls | $cmd

Este método evita o sutilezas de eval . Veja também aqui .

Uma abordagem melhor: matrizes

Uma abordagem mais sofisticada usaria bash arrays no lugar de strings simples:

$ cmd=(sort -n)
$ ls | "${cmd[@]}"

A vantagem dos arrays torna-se importante assim que você precisar do comando cmd para conter argumentos citados.

    
por 01.01.2015 / 03:48
5

Você pode eval uate o comando:

eval "ls $pipedargument"

ou melhor ainda definir função como:

sorted() { "$@" | sort -n; }

e mais tarde, chame-o com os argumentos desejados:

sorted ls /tmp
    
por 01.01.2015 / 03:46
-1

Eu usaria uma função para isso. Algo como:

### usage pipedargument cmd args ###

pipedargument()
{
    sort -n <<< "$( "$@" )"
}

$ pipedargument /sbin/ifconfig eth0
      RX bytes:5904986765 (5.4 GiB)  TX bytes:714370767 (681.2 MiB)
      RX packets:5981427 errors:0 dropped:0 overruns:0 frame:0
      TX packets:4403989 errors:0 dropped:0 overruns:0 carrier:0
      UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
      collisions:0 txqueuelen:1000 
      inet addr:XXX.XXX.X.XX  Bcast:XXX.XXX.X.XXX  Mask:255.255.255.0
      inet6 addr: xx00::0x0x:00xx:xx0:000/00 Scope:Link
eth0      Link encap:Ethernet  HWaddr 0x:0x:00:x0:00:00
    
por 05.01.2015 / 04:19