쉘 스크립트에 명령줄 인수를 전달하는 동안 I/O 오류가 발생했습니다.

쉘 스크립트에 명령줄 인수를 전달하는 동안 I/O 오류가 발생했습니다.

bright.sh디스플레이 밝기를 수동으로 조정하기 위해 한 줄짜리 bash 스크립트( )를 작성했습니다 .

sudo sh -c 'echo "$1" > /sys/class/backlight/intel_backlight/brightness'

여기서는 터미널에서 밝기 값을 가져와서 echo 명령에 매개변수로 전달합니다. 그러나 스크립트를 실행할 때 다음 I/O 오류가 발생합니다.

sh: echo: I/O error

터미널에서 매개변수를 성공적으로 전달하고 밝기를 수동으로 제어하려면 어떻게 해야 합니까? 사용 예는 다음과 같습니다.

./bright.sh 230

답변1

$1스크립트에서 sh -c첫 번째 명령줄 인수로 확장됩니다.저것스크립트를 첫 번째 명령줄 인수로 호출하는 대신 스크립트를 사용합니다( sh -c스크립트가 작은따옴표로 묶여 있기 때문).

$1올바른 해결책은 호출 스크립트의 값을 sudo스크립트에 주입하는 것이 아니라(이는 모든 종류의 흥미로운 코드 주입 취약점을 허용함) $1이를 외부 스크립트에서 내부 스크립트로 전달하는 것입니다.

sudo sh -c 'printf "%s\n" "$1" > /sys/class/backlight/intel_backlight/brightness' sh "$1"

또는 sudo tee루트로 파일에 씁니다.

printf '%s\n' "$1" | sudo tee /sys/class/backlight/intel_backlight/brightness >/dev/null

파일에 인쇄된 데이터가 항상 정수인 경우 %d대신 .printf%s

답변2

외부에 작은따옴표를 넣어 이 문제를 해결할 수 있습니다 $1. 이것이 최선의 접근 방식인지 확실하지 않습니다.

이제 작업 스크립트는 다음과 같습니다.

sudo sh -c 'echo '$1' > /sys/class/backlight/intel_backlight/brightness'

답변3

예, 질문을 보셨습니다(답변https://unix.stackexchange.com/a/481424/4778), 하지만 여전히 인용해야 합니다 $1(만일의 경우를 대비해). 그리고 인터프리터( #!…) 를 지정하는 것을 잊지 마세요.

«솔루션이 올바르게 참조되지 않았고 보안 버그가 있었기 때문에 제거되었습니다. @Kusalananda의 답변을 참조하세요. »

문자열을 함께 터치하여 연결할 수 있습니다. 큰따옴표는 $expression을 확장하지만 작은따옴표는 확장하지 않습니다. 이 경우 나머지 텍스트에는 $s가 없으므로 차이가 없으므로 모두 큰따옴표로 묶을 수 있습니다.

관련 정보