이 명령을 변수로 리디렉션하고 싶습니다.
{
printf 'scan on\n\n'
sleep 10
printf 'quit \n\n'
} | bluetoothctl
나는 이것을 시도한다:
variable=$(printf 'scan on\n\n' sleep 10 printf 'quit \n\n' | bluetoothctl)
echo $variable
하지만 빈 출력이 나타납니다. 나는 또한 그것을 분할하려고 시도했습니다.
variable=$(printf 'scan on\n\n' | bluetoothctl)
sleep 10
printf 'quit \n\n'| bluetoothctl
echo $variable
하지만 이번에는
Agent registered
[bluetooth]# quit
stdout
변수를 실행할 때 인쇄된 첫 번째 명령의 출력을 어떻게 리디렉션할 수 있나요 ?
답변1
오직:
variable=$(
{
printf 'scan on\n\n'
sleep 10
printf 'quit \n\n'
} | bluetoothctl
)
명령 대체의 내부는 임의의 쉘 코드1일 수 있으며 한 줄에 있을 필요는 없습니다.
bluetoothctl
여기서는 전체 파이프의 출력을 캡처하려고 합니다(실제로 다른 모든 명령의 stdout이 파이프로 리디렉션되므로 이는 stdout의 출력이 됩니다 bluetoothctl
).
다음을 사용하여 출력을 캡처할 수도 있습니다 bluetoothctl
.
{
printf 'scan on\n\n'
sleep 10
printf 'quit \n\n'
} | variable=$(bluetoothctl)
하지만 에서 bash
작동하려면 마지막 파이프라인 구성 요소에 대한 옵션을 설정해야 합니다 lastpipe
( shopt -s lastpipe
, 비대화형 셸 인스턴스에만 해당).아니요서브셸에서 실행합니다.
그러나 여기서는 파이프가 필요하지 않습니다. 다음과 같이 할 수 있습니다.
variable=$(bluetoothctl --timeout 10 scan on)
변수의 내용을 표시하려면 다음 구문을 기억하세요.
printf '%s\n' "$variable"
아니요 .echo $variable
자세한 내용은 다음을 참조하세요.
여기의 출력에는 bluetoothctl
색상 표시 이스케이프 시퀀스와 줄 내용을 지우는 데 사용되는 이스케이프 시퀀스가 포함되어 있습니다. 따옴표 없이 두면 $variable
해당 내용이 분할+글로브되어 전달될 임의의 단어 목록이 생성되고 공백으로 구분되어 출력됩니다 echo
. echo
따라서 마지막 단어가 다음으로 끝나면 모든 내용을 한 줄에 작성하게 됩니다.명확한 선시퀀스(내 테스트에서 수행한 작업 \r\e[K
:캐리지 리턴다음은생산라인 끝까지 클리어순서), 빈 줄만 표시됩니다.
1 일부 쉘은 bash
일치하지 않는 괄호가 있는 코드를 차단하는 데 사용되지만(예: 코드에 케이스 문 case $x in foo)
이나 불균형 주석이 포함된 경우 )
) 쉘 파서는 이를 )
명령 대체를 닫는 것으로 착각합니다.
답변2
오류는 세미콜론 누락입니다(그렇지 않으면 개행 문자와 동일함). 출력 구조를 보려면 큰따옴표를 추가하세요. 노력하다:
variable=$( { printf 'scan on\n\n' ; sleep 10 ; printf 'quit \n\n' ; } | bluetoothctl)
echo "$variable"
답변3
가능한 대안은 간단한 expect
스크립트입니다.
#!/usr/bin/expect
spawn bluetoothctl
send "scan on\r"
sleep 10
send "quit \r"
expect eof
\r
"Return/Enter 키 누르기"와 동일합니다. 실행파일을 만들어서 실행해보세요.