$variable에서 | 파이프 문자를 사용하면 bash에서 다른 매개변수로 처리됩니다. 이를 이스케이프하는 방법은 무엇입니까?

$variable에서 | 파이프 문자를 사용하면 bash에서 다른 매개변수로 처리됩니다. 이를 이스케이프하는 방법은 무엇입니까?

나는 이와 같은 bash 스크립트를 가지고 있습니다

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

하지만 오류가 발생합니다.

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

"| sort -n"내용을 에 전달된 매개변수 로 취급하는 것 같습니다 ls.

일반 파이프 명령처럼 처리되도록 어떻게 이스케이프 처리합니까?

이것을 조건부로 설정하려고 합니다 $pipedargument. 조건부로 다른 버전의 명령을 실행할 수 있을 것 같지만 위와 같이 작동하도록 할 수 있는 방법이 있는지 궁금합니다.

답변1

|당신 말이 맞아요, 이렇게 하면 안 돼요 . 그 이유는 쉘이 변수 대체를 수행하기 전에 이미 파이프를 찾아 명령으로 분할하기 때문입니다. 따라서 |그냥 또 다른 캐릭터로 간주됩니다.

한 가지 가능한 해결 방법은 파이프 문자를 문자 그대로 배치하는 것입니다.

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

cat파이프가 필요하지 않은 경우 "nop" 또는 자리 표시자로 사용할 수 있습니다 .

$ cmd=cat
$ ls | $cmd

이 방법은평가의 미묘함. 당신은 또한 볼 수 있습니다여기.

더 나은 접근 방식: 배열

보다 정교한 접근 방식은 bash일반 문자열 대신 배열을 사용하는 것입니다.

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

cmd인용된 인수를 포함하는 명령이 필요할 때 배열의 장점이 중요해집니다.

답변2

eval다음 명령을 사용할 수 있습니다 .

eval "ls $pipedargument"

또는 다음과 같이 함수를 정의하는 것이 더 좋습니다.

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

그런 다음 필수 매개변수를 사용하여 호출하세요.

sorted ls /tmp

답변3

나는 이것을 위해 함수를 사용할 것입니다. 그것은 다음과 같습니다:

### 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

관련 정보