Bash의 프로세스 대체를 HERE 문서와 결합하는 방법은 무엇입니까?


14

Bash 버전 4.2.47 (1)-릴리스에서 HERE-dcoument와 같은 형식의 텍스트를 연결하려고 할 때

cat <(fmt --width=10 <<FOOBAR
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
) # I want this paranthesis to end the process substitution.

다음과 같은 오류가 발생합니다.

bash: bad substitution: no closing `)' in <(fmt --width=10 <<FOOBAR
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
)

또한 HERE 문서 (예 : write)를 인용하고 싶지 않습니다. 여기서 <'FOOBAR'변수를 대체하고 싶기 때문입니다.


정말로 cat전화 가 필요 합니까? 왜 전화를 놔두지 fmt않겠습니까?
iruvar

2
나는 그것이 좋은 예임을 인정해야한다. 내 실제 요구는 그보다 더 복잡합니다.
팀 프리 스케

1
당신 (Even"(Even"그것을 대체 할 때 작동 한다는 것은 흥미 롭습니다 . 동일합니다 \(Even. 파싱 ​​버그 인 것 같습니다. Bash는 여전히 중괄호를 찾고 있었지만 여기 문서를 읽는 맥락에서 두 컨텍스트가 서로 모순됩니다.
라파엘 아 렌스

1
이것은 bash부수적 으로 4.3에서 수정되었습니다 .
chepner

답변:


7

프로세스 대체는 이와 거의 같습니다.

예-프로세스 대체 메커니즘

1 단계-fifo를 만들어 출력

$ mkfifo /var/tmp/fifo1
$ fmt --width=10 <<<"$(seq 10)" > /var/tmp/fifo1 &
[1] 5492

2 단계-fifo 읽기

$ cat /var/tmp/fifo1
1 2 3 4
5 6 7 8
9 10
[1]+  Done                    fmt --width=10 <<< "$(seq 10)" > /var/tmp/fifo1

HEREDOC 내에서 parens를 사용하는 것도 괜찮습니다.

예-FIFO 만 사용

1 단계-FIFO로 출력

$ fmt --width=10 <<FOO > /var/tmp/fifo1 &
(one)
(two
FOO
[1] 10628

2 단계-FIFO 내용 읽기

$ cat /var/tmp/fifo1
(one)
(two

당신이 겪고있는 문제는 프로세스 대체가 그 <(...)안에 Parens의 중첩을 신경 쓰지 않는 것입니다.

예-프로세스 하위 + HEREDOC이 작동하지 않습니다

$ cat <(fmt --width=10 <<FOO
(one)
(two
FOO
)
bash: bad substitution: no closing `)' in <(fmt --width=10 <<FOO
(one)
(two
FOO
)
$

파렌을 탈출하면 약간 진정되는 것처럼 보입니다.

예-탈출구

$ cat <(fmt --width=10 <<FOO                 
\(one\)
\(two
FOO
)
\(one\)
\(two

그러나 실제로 원하는 것을 제공하지는 않습니다. 파 렌스를 균형있게 만드는 것도 진정시키는 것처럼 보입니다.

예-밸런싱 밸런싱

$ cat <(fmt --width=10 <<FOO
(one)
(two)
FOO
)
(one)
(two)

Bash에서와 같이 복잡한 문자열이있을 때마다 거의 항상 먼저 문자열을 구성하고 변수에 저장 한 다음 변수를 통해 사용하여 까다로운 한 라이너를 만들려고 시도하지 않습니다. 깨지기 쉬운.

예-변수 사용

$ var=$(fmt --width=10 <<FOO
(one)
(two
FOO
)

그런 다음 인쇄하십시오.

$ echo "$var"
(one)
(two

참고 문헌


3

이것은 단지 해결 방법입니다. 프로세스 대체를 사용 fmt하는 cat대신 파이프

fmt --width=10 <<FOOBAR | cat 
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR

1
나는 당신의 "해결책"을 시도했고 그것은 나를 위해 일할 것입니다. 감사. 그러나 여전히 프로세스 대체 내부에 중첩 된 HERE 문서 조합이 작동하지 않는 이유를 파악하고 싶습니다. 답이 있습니까?
Tim Friske

@ TimFriske, 나는 bash이 사이트 의 마법사 중 하나에서 마법사 중 하나를 연기해야 합니다. 배쉬 파서 내부에 대한 나의 지식은 가장
적다

2

이것은 오래된 질문이며, 이것이 당신이 고안된 예라는 것을 알기 때문에 (따라서 올바른 해결책은 이 경우에는 cat |전혀 사용 하지 않거나 실제로는 전혀 사용 하지 않는다는 cat것입니다), 나는 일반적인 경우에 대한 답변을 게시 할 것입니다. 함수에 넣고 대신 사용하여 해결합니다.

fmt-func() {
    fmt --width=10 <<FOOBAR
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
}

그런 다음 사용하십시오

cat <(fmt-func)

감사합니다! 정확히 내가 찾던 것.
piarston
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.