read
구성 스크립트를 다운로드하고 일부 구성 매개변수를 읽고 실행하고 싶습니다 .
curl http://example.com/provisioning.sh | sh
문제는 기본값을 제공하기 위해 매개변수를 사용하여 read
스크립트에서 명령을 호출하는 것 입니다.-i
read -p "Name: " -i joe name
echo $name
스크립트를 다운로드하고 +x
권한을 설정하고 실행하면 모든 것이 정상입니다.
cat provisioning.sh | sh
다음을 사용하여 실행하거나 sh provisioning.sh
다음과 같이 실패 하면 :
read: Illegal option -i
sh를 통해 실행하는 경우 기본값 읽기에 대한 지원이 제공되지 않는 이유는 무엇입니까?
하지만 어쨌든 삭제 -i
하고 남길게요
read -p "Name: " name
echo $name
이제 를 통해 스크립트를 실행하면 cat provisioning.sh | sh
아무 작업도 수행되지 않습니다. 왜 그런 겁니까?
우분투 14.04.
답변1
의 출력을 파이프 curl
하면 sh
스크립트 텍스트를 셸의 표준 입력으로 만들어 실행할 명령으로 수신하게 됩니다. 그 후에는 아무것도 남지 않습니다 read
. 시도하더라도 터미널 입력에 연결되어 있지 않기 때문에 터미널 입력에서 아무것도 얻지 못합니다. 파이프는 sh
프로세스의 표준 입력을 대체했습니다 .
다음 질문 read -i
은아니요POSIX sh 함수이지만 에서 지원하는 확장입니다 bash
.우분투는dash
, 기본적으로 최소한의 확장을 갖춘 최소한의 POSIX 호환 셸입니다 /bin/sh
. 이것이 -i
옵션을 명시적으로 거부하는 이유입니다(지원하긴 하지만 -p
).
더 강력한 셸을 직접 사용하는 경우 다음을 시도해 볼 수 있습니다.
bash <(curl http://example.com/provisioning.sh)
bash
의 출력을 읽기 위한 파이프를 생성 curl
하고 이를 스크립트 파일 인수로 제공합니다. 이 경우 스크립트의 표준 입력은 여전히 터미널에 연결되어 있으며 read
작동합니다(그러나 해당 줄 아래에 중요한 경고가 있습니다).
제가 또 주목하고 싶은 점은" curl | sh
" 예일반적으로 말하면 찌푸린 얼굴 ~ 위에명백한 보안 문제이지만 스크립트가 처한 상황은 사용자가 가장 잘 알고 있습니다.
답변2
또 다른 이식성 있는 접근 방식은 또 다른 파일 설명자를 만드는 것입니다.
exec 3<>/dev/tty
read -u 3 -p "Gimme some stuff: " stuff
내 경우에는 이것이 작동하도록 스크립트에서 빠르게 찾기 및 바꾸기를 수행했습니다.
exec 3<>/dev/tty
read_cmd="read -u 3"
$read_cmd -p "name: " my_name
$read_cmd -p "email: " my_email
$read_cmd -s -p "password: " my_password