$! 명령줄에서는 작동하지 않습니다

$! 명령줄에서는 작동하지 않습니다

나는 다음을 실행 중입니다bash 명령줄 프롬프트에서 직접:

$ PIDS= ;while read name; do (cd $name; npm install) & echo started install; PIDS+=($!); done < <(\ls); for pid in ${PIDS[@]}; do wait $pid; done;

알겠어요:

-bash: !: event not found

!"$!"를 먼저 변수로 보는 대신 명령 기록 대체를 수행하는 데 기호가 사용된다고 가정합니다 .


bash 명령줄에서 직접 실행하는 경우 마지막 백그라운드 프로세스의 pid를 얻는 방법은 무엇입니까?

답변1

4.3과 4.4에서는 문제를 재현 할 수 없으므로 bash일반적인 답변은 다음과 같습니다.

문제는 기록 교체가 시작되는 시점 !에 발생합니다 (기본적으로 대화형 셸을 통해 활성화됨).PIDS+=($!)!

역사 비활성화로 바꾸거나 set +H인용하거나 !(이전 내용으로 인해 여기서는 바람직하지 않음 $) 그 뒤에 공백을 추가하십시오 !. Bash 매뉴얼은 다음과 같습니다.

!공백, 개행, 캐리지 리턴 =또는 ((내장 shopt를 사용하여 extglob 셸 옵션이 활성화된 경우)이 뒤따르지 않는 한 기록 교체를 활성화합니다.

그러면 명령줄은 다음과 같습니다.

PIDS=()
while read name; do
    (cd "$name"; npm install) &
    echo started install
    PIDS+=( $! )
done < <(\ls)
wait "${PIDS[@]}"

노트:

  • 여기서는 한 줄의 코드로 제한되지 않습니다.
  • 변수 주위에 올바른 따옴표를 추가했습니다.
  • 동시에 여러 PID를 기다릴 수 있습니다.

답변2

~에서배쉬 변경 로그:

이 문서에서는 bash-4.2-alpha 버전과 이전 버전인 bash-4.1-release 간의 변경 사항을 자세히 설명합니다. (…)

3. Bash의 새로운 기능(...)

유. 역사적 확장은 더 이상 $!변수 확장을 확장하지 않습니다.

이전 버전의 bash PIDS+=($!)에 대처하려면 PIDS+=($! ).!

관련 정보