ksh의 경우 값을 구분하기 위한 편의 방법으로 read를 사용합니다.
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
2 1
$
하지만 Bash에서는 실패합니다.
$ echo 1 2 3 4 5 | read a b dump
$ echo $b $a
$
매뉴얼 페이지에서 실패 이유를 찾지 못했습니다. 어떤 아이디어가 있습니까?
답변1
bash
파이프라인의 오른쪽을 실행합니다.안에서브쉘 컨텍스트, 따라서 변수에 대한 변경 사항(완료된 작업 read
)은 유지되지 않습니다. 명령이 끝날 때 하위 쉘이 저장되면 사라집니다.
대신에 다음을 사용할 수 있습니다.프로세스 교체:
$ read a b dump < <(echo 1 2 3 4 5)
$ echo $b $a
2 1
이 경우 read
기본 셸에서 실행되고 출력 생성 명령은 하위 셸에서 실행됩니다. <(...)
문법만들다read
서브쉘을 만들고 출력을 파이프에 연결하여 일반 입력으로 리디렉션합니다.<
작업. read
메인 셸에서 실행 중이므로 변수가 올바르게 설정되었습니다 .
주석에서 지적했듯이 실제로 문자열을 어떻게든 변수로 분할하는 것이 목표라면 다음을 사용할 수 있습니다.여기에 있는 문자열:
read a b dump <<<"1 2 3 4 5"
할 일이 더 있다고 생각하지만 그렇지 않다면 이것이 더 나은 선택입니다.
답변2
이는 사용자가 관찰한 불행한 차이를 초래하는 권한 및 동작 bash
으로 인한 버그 가 아닙니다 .POSIX
bash
ksh
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_12
또한 다중 명령 파이프라인의 각 명령은 하위 셸 환경에 있지만 확장으로 파이프라인의 일부 또는 모든 명령을 현재 환경에서 실행할 수 있습니다. 다른 모든 명령은 현재 쉘 환경 내에서 실행되어야 합니다.
그러나 bash 4.2
최신 버전 에서는 lastpipe
비대화형 스크립트에서 이 옵션을 설정하여 예상된 결과를 얻을 수 있습니다. 예를 들면 다음과 같습니다.
#!/bin/bash
echo 1 2 3 4 5 | read a b dump
echo before: $b $a
shopt -s lastpipe
echo 1 2 3 4 5 | read a b dump
echo after: $b $a
산출:
before:
after: 2 1