ksh88에서 Here-Strings를 사용할 수 있습니까?

ksh88에서 Here-Strings를 사용할 수 있습니까?

ksh 스크립트의 3가지 변수 중 하나에서 3개의 단어를 추출하고 싶습니다. ksh93에서 이 줄을 사용했는데 훌륭하게 작동합니다.

read A B C <<< $line

ksh88에서 위 명령을 실행할 때 다음 오류가 발생합니다.

syntax error at line ## : '<' unexpected

ksh88에서 동일한 작업을 어떻게 수행할 수 있나요?

답변1

ksh88아니요, 여기 문자열은 및 에서 사용할 수 없습니다 pdksh. 그러나 최신 ksh93(원래 AT&T Korn Shell) 및 ( mksh현재 활발히 개발 중인 pdksh스핀오프 )에서 사용할 수 있습니다.

<<<ksh93, mksh, GNU bashzsh.

귀하의 구체적인 질문 ...

read A B C <<< $line

...이 문제를 해결할 수 있습니다(Korn 쉘).

print -r -- $line |&
read -p A B C

이를 사용할 수도 있지만(POSIX 셸) tmpfile 성능 저하가 있습니다(반면에 <<<있을 수도 있음).

read A B C <<EOF
$line
EOF

하지만 단어를 분리하고 싶다면 다음을 수행하세요.

set -A arrname -- $line

${arrname[0]}그런 다음 대신 사용 $A하고 ${arrname[1]}교체하십시오 $B. 단지 세 개의 요소로 분할되어도 멈추지 않는다는 점일 뿐입니다. 따라서 $line" foo bar baz bla" 이면 $C"baz bla"가 포함되고 ${arrname[2]}"baz"가 있으면 ${arrname[3]}"bla"가 포함됩니다.

그러나 위치 매개변수가 필요하지 않은 경우 다음을 수행할 수 있습니다.

set -- $line
A=$1; shift
B=$1; shift
C=$*

그러나 단어 수가 3개 미만이면 오류가 발생합니다(확실하지 않은 경우 확인 shift하거나 (잠재적으로 더 느린) 확인을 먼저 사용하십시오).$line$#[[ $line = *' '*' '[! ] ]]

이는 set … $line와일드카드도 수행하므로(상기시켜 주신 Stéphane에게 감사드립니다) 이전에 필요합니다 set -o noglob(일반적으로 이후에 이전 상태를 복원할 수 있습니다 set +o noglob).

전체 공개: 저는 mksh개발자입니다.

답변2

아니요, 여기 문자열은 zsh1991년 2.0(및/또는 Unix 포트) 에서 가져온 것입니다 rc. 각각의 작성자는 당시 아이디어를 교환했으며 두 사람 중 누가 아이디어를 가졌는지 또는 그의 쉘 첫 번째 중간에 포함했는지는 확실하지 않습니다.

2.05b(2002)의 bash, m+(2002)의 ksh93, R33(2008)의 mksh, 2.7(2009)의 yash에 추가되었습니다.

ksh88에는 새로운 기능이 없습니다.

여기에 있는 문서( <<) 자체는 1970년대 후반 Bourne-shell에서 나온 것입니다.

read A B C하나 읽어보세요논리적줄은 매우 특정한 방식으로 삽입되며 A변수 B( 기본값은 IFS 공백 문자 1만 포함하는 C다소 덜 구체적 $IFS)와 백슬래시가 이스케이프 및 줄 연속 문자 역할을 하므로 이 C역시 매우 복잡해집니다. 없이 같은 일을 하는 것은 매우 어려울 것입니다 read.

어쨌든 여기 <<<와 똑같고 <<구문만 다릅니다.

read A B C << EOF
$var
EOF

정확히 똑같다

read A B C <<< "$var" # note that some versions of bash need the quotes

모든 껍질에. 두 경우 모두, 쉘은 내용과 추가된 개행 문자를 포함하는 삭제된 임시 파일을 생성합니다(일부 쉘은 대신 파이프를 사용하지만). 그럼 read읽어봐논리적행(백슬래시로 계속되는 여러 물리적 행에 있을 수 있음)을 입력하고 복잡한 규칙을 사용하여 변수를 채웁니다.

$varto (SPC/TAB 구분)의 처음 3워드만 할당 하고 $A,$B$C

  • $IFS여전히 기본값이 포함되어 있습니다.
  • 변수에 백슬래시와 개행 문자가 포함되어 있지 않습니다.
  • 이 변수에는 3개의 단어만 포함됩니다.

처음 세 단어에 대해 다음을 수행할 수 있습니다.

function split_into {
  typeset words IFS v i=0
  set -o noglob

  set -A words -- $1; shift
  for v do
    eval "$v=\${words[i]}"
    ((i += 1))
  done
}

split_into "$var" A B C
  
  

^IFS 공백 문자, 각 POSIX는 로케일로 분류된 문자 이며 ksh88(POSIX 사양의 기반) 및 대부분의 셸에서 [:space:]발생하는 것처럼 이는 여전히 SPC, TAB 및 NL로 제한됩니다. $IFS이와 관련하여 제가 찾은 유일한 POSIX 호환 셸은 입니다 yash. ksh93( bash5.0 기준) 다른 공백(예: CR, FF, VT...)도 포함하지만 단일 바이트 공백으로 제한됩니다(예: Solaris)(일부 영역에는 단일 바이트의 잘림 방지 공백이 포함됨)

관련 정보