파이프의 출력을 변수에 넣으려고 합니다. 나는 다음을 시도했다:
echo foo | myvar=$(</dev/stdin)
echo foo | myvar=$(cat)
echo foo | myvar=$(tee)
그러나 $myvar
그것은 비어있었습니다.
나는하고 싶지 않다 :
myvar=$(echo foo)
서브 쉘을 생성하고 싶지 않기 때문입니다.
어떤 아이디어가 있나요?
편집하다:파이프 앞의 명령을 사용하려면 전역 변수를 편집해야 하는데 서브셸에서는 이를 수행할 수 없기 때문에 서브셸을 생성하고 싶지 않습니다. 그럴 수 있어? 상황은 echo
단순화하기 위한 것입니다. 그것은 다음과 같습니다:
complex_function | myvar=$(</dev/stdin)
왜 이것이 작동하지 않는지 이해하지 못합니다. 예를 들면 다음과 같습니다.
complex_function | echo $(</dev/stdin)
답변1
올바른 해결 방법은 다음 명령 대체를 사용하는 것입니다.
variable=$(complex_command)
좋다
message=$(echo 'hello')
(또는 message=hello
이 경우에는).
귀하의 파이프라인:
echo 'hello' | message=$(</dev/stdin)
또는
echo 'hello' | read message
실제로 작동합니다. 유일한 문제는 서브셸에서 파이프라인의 두 번째 부분을 실행하는 셸을 사용하고 있다는 것입니다. 파이프가 종료되면 하위 쉘이 파괴되므로 값이 $message
쉘에 유지되지 않습니다.
여기에서 작동 방식을 확인할 수 있습니다.
$ echo 'hello' | { read message; echo "$message"; }
hello
...그러나 서브쉘의 환경은 독립적이므로(그리고 사라집니다):
$ echo "$message"
(출력 없음)
ksh93
한 가지 솔루션은 더 스마트한 솔루션 으로 전환하는 것입니다 .
$ echo 'hello' | read message
$ echo "$message"
hello
또 다른 해결책 은 쉘 옵션을 bash
설정하는 것입니다 . lastpipe
그러면 파이프라인의 마지막 부분이 현재 환경에서 실행됩니다. 그러나 lastpipe
작업 제어가 활성화되지 않아야 하므로 대화형 셸에서는 작동하지 않습니다 .
#!/bin/bash
shopt -s lastpipe
echo 'hello' | read message
echo "$message"
답변2
명령 대체 사용:
myvar=`echo foo`
또는
myvar=$(echo foo)
답변3
전역 변수를 수정하고 그 내용을 stdout에 인쇄하는 함수가 주어지면:
global_variable=old_value
myfunction() {
global_variable=new_value
echo some output
}
ksh93
mksh R45 이상 에서는 다음을 사용할 수 있습니다.
var=${
myfunction
}
그 다음에:
$ print -r -- "$global_variable, $var"
new_value, some output
${ ...; }
서브쉘을 생성하지 않는 명령 대체 형식입니다. 내장 명령의 경우 출력을 파이프에 기록하는 대신(이를 위해서는 교착 상태를 피하기 위해 파이프에서 읽고 쓰는 다른 프로세스가 필요함) ksh93
아무 것도 출력하지 않고 내용을 수집하여 내보냈을 것입니다. 확장을 위해 올라왔습니다. mksh
대신 임시 파일을 사용하세요.
$ ksh -c 'a=${ b=123; echo foo;}; print -r -- "$a $b"'
foo 123
fish
명령 대체 동작도 ksh93과 유사합니다 ${ ...; }
.
$ fish -c 'set a (set b 123; echo foo); echo $a $b'
foo 123
대부분의 다른 쉘에서는 임시 파일을 사용합니다.
myfunction > file
var=$(cat file) # can be optimised to $(<file) with some shells
Linux에서는 bash
4.4 이하 버전을 사용하거나 zsh
(임시 파일 사용 <<<
) 다음을 수행할 수 있습니다.
{
myfunction > /dev/fd/3 &&
var=$(cat<&3)
} 3<<< ''
에서는 zsh
다음 작업도 수행할 수 있습니다.
() {
myfunction > $1
var=$(<$1)
} =(:)
ksh, zsh 또는 bash와 같은 Korn 유사 쉘에서 $(cmd...)
표준 형식이나 변형 $(<file)
의 명령 대체 ${ cmd...; }
는 모든 후행 개행 문자( file
또는 출력 cmd
)를 제거합니다. 바라보다셸: 명령 대체에서 후행 개행('\n')을 유지합니다.이 문제를 해결하는 방법을 알아보세요.
에서 출력의 각 행을 fish
배열 의 개별 요소에 할당합니다 . 출력 또는 . 버전 3.4.0부터 Korn 셸의 동작과 유사한 동작(후행 줄 바꿈 모두 제거)도 지원됩니다.set var (cmd)
cmd
$var
$var
cmd
foo
foo<newline>
fish
set var "$(cmd)"
답변4
임시 파일을 사용하여 복잡한 함수의 결과를 저장한 다음 처리를 위해 임시 파일에서 값을 읽습니다.
# Create a temp file for storage
tmppath=$(mktemp)
# run the command and get the output to the temp file
complex_command > "${tmppath}"
# read the file into variable
message=$(cat "${tmppath}")
# use the variable
echo "$message"
rm -f "${tmppath}"
이용방법 mktemp
을 참고해주세요쉘 스크립트에서 임시 파일을 만드는 방법은 무엇입니까?