어떤 사람들은 read
선을 읽는 명령 인 잘못된 개념을 가지고 있습니다 . 그렇지 않습니다.
read
(역 슬래시 연속) 줄에서 단어 를 읽습니다 . 여기서 단어는 $IFS
구분되고 역 슬래시 는 구분 기호를 이스케이프하거나 줄을 계속 사용하는 데 사용할 수 있습니다.
일반적인 구문은 다음과 같습니다.
read word1 word2... remaining_words
read
이스케이프되지 않은 줄 바꿈 문자 (또는 입력 끝)를 찾을 때까지 한 번에 한 바이트 씩 stdin을 읽고 복잡한 규칙에 따라이를 나누고 그 결과를 $word1
, $word2
... 로 저장합니다 $remaining_words
.
예를 들어 다음과 같은 입력에서 :
<tab> foo bar\ baz bl\ah blah\
whatever whatever
기본값이 인 $IFS
경우 다음 read a b c
을 지정합니다.
$a
⇐ foo
$b
⇐ bar baz
$c
⇐ blah blahwhatever whatever
이제 하나의 인수 만 전달하면 해당되지 않습니다 read line
. 아직 read remaining_words
입니다. 백 슬래시 처리는 여전히 수행되며 IFS 공백 문자는 여전히 시작과 끝에서 제거됩니다.
이 -r
옵션은 백 슬래시 처리를 제거합니다. 따라서 위의 동일한 명령 -r
이 대신
$a
⇐ foo
$b
⇐ bar\
$c
⇐ baz bl\ah blah\
분할 부분의 $IFS
경우 IFS 공백 문자 (공백 및 탭 (여기서는 -d를 사용하지 않는 한 여기서는 중요하지 않음))의 두 가지 문자 클래스가 있음을 인식하는 것이 중요합니다 . $IFS
) 및 기타 의 기본값으로 설정 하십시오. 이 두 클래스의 캐릭터에 대한 처리 방법이 다릅니다.
로 IFS=:
( :
아닌 IFS 공백 문자 인), 같은 입력 :foo::bar::
으로 분할된다 ""
, "foo"
, ""
, bar
과 ""
(와 여분의 ""
그 제외하고는 중요하지 않습니다하지만 일부 구현과 함께 read -a
). 우리가 대체하면되지만 :
공간, 분할 만에 완료 foo
하고 bar
. 그것은 앞뒤의 것들을 무시하고 그것들의 순서는 하나처럼 취급됩니다. 공백 문자와 공백 문자가 아닌 문자를 조합 할 때 추가 규칙이 있습니다 $IFS
. 일부 구현은 IFS ( IFS=::
또는 IFS=' '
) 의 문자를 두 배로하여 특수 처리를 추가 / 제거 할 수 있습니다 .
따라서 여기서 앞뒤 이스케이프 처리되지 않은 공백 문자를 제거하지 않으려면 IFS에서 해당 IFS 공백 문자를 제거해야합니다.
공백이 아닌 IFS 문자의 경우에도 입력 행에 해당 문자 중 하나만 포함 되고 POSIX 쉘 ( 또는 일부 버전이 아님)이 IFS=: read -r word
있는 입력과 같은 행의 마지막 문자 인 경우 해당 입력 하나로 간주 하는 쉘에서 문자가 있기 때문에 단어 로 간주됩니다 터미네이터 , 그래서 포함 하지 .foo:
zsh
pdksh
foo
$IFS
word
foo
foo:
따라서 read
내장으로 한 줄의 입력을 읽는 표준 방법 은 다음 과 같습니다.
IFS= read -r line
(대부분의 read
구현에서는 NUL 문자가에서 제외하고 지원되지 않기 때문에 텍스트 줄에서만 작동합니다 zsh
.)
var=value cmd
구문을 사용하면 IFS
해당 cmd
명령 기간 동안 만 다르게 설정 됩니다.
연혁
read
내장은 Bourne 쉘에 의해 도입 읽고 이미 한 단어 가 아니라 라인. 최신 POSIX 셸에는 몇 가지 중요한 차이점이 있습니다.
Bourne 쉘 은 Korn 쉘에 의해 도입 된 옵션을 read
지원하지 않으므로 -r
, 입력과 같은 것을 사전 처리하는 것 이외의 백 슬래시 처리를 비활성화 할 방법이 없습니다 sed 's/\\/&&/g'
.
Bourne 쉘에는 두 개의 클래스 클래스 (ksh에 의해 다시 도입 됨)라는 개념이 없었습니다. 보른에서 IFS의 공백 문자 KSH에서하는 모든 문자가 같은 치료를 받아야 쉘, 즉 IFS=: read a b c
같은 입력에 foo::bar
할당합니다 bar
을 $b
하지 빈 문자열입니다.
Bourne 쉘에서
var=value cmd
cmd
내장 (있는 경우 read
)이면 완료 후로 var
설정된 상태로 유지됩니다 . Bourne 쉘에서는 확장뿐만 아니라 모든 것을 분할하는 데 사용 되기 때문에 특히 중요 합니다. 또한 Bourne 쉘에서 공백 문자를 제거하면 더 이상 작동하지 않습니다.value
cmd
$IFS
$IFS
$IFS
"$@"
Bourne 쉘에서, 화합물 명령을 리디렉션 (같은 초기 버전에서도 일을이 서브 쉘에서 실행됩니다 read var < file
또는 exec 3< file; read var <&3
작동하지 않았다), 그래서 Bourne 쉘이 사용하기에 그것은 드문 read
단말기에 사용자 입력을 제외한 아무것도 (그 라인 연속 처리가 의미가있는 곳)
HP / UX와 같은 일부 Unices에는 util-linux
여전히 line
한 줄의 입력을 읽는 명령이 있습니다 ( 단일 UNIX 사양 버전 2 까지 표준 UNIX 명령으로 사용됨 ).
기본적으로 head -n 1
한 줄에 두 바이트 이상 읽지 않도록 한 번에 한 바이트 씩 읽는다 는 점을 제외 하면 동일 합니다. 이러한 시스템에서 다음을 수행 할 수 있습니다.
line=`line`
물론 이것은 새로운 프로세스를 생성하고 명령을 실행하고 파이프를 통해 출력을 읽는 것을 의미하므로 ksh보다 훨씬 덜 효율적 IFS= read -r line
이지만 훨씬 더 직관적입니다.