그래서 저는 이 가이드에서 이 스크립트를 얻었습니다: www.tldp.org/LDP/abs/abs-guide.pdf
LOG_DIR=/var/log
ROOT_UID=0
LINES=50
E_XCD=86
E_NOTROOT=87
if [ "$UID" != "$ROOT_UID" ]
then
echo "Must be root to run this script."
exit $E_NOTROOT
fi
if [ -n "$1" ]
then
lines=$1
else
lines=$LINES
fi
cd $LOG_DIR
if [ 'pwd' != "$LOG_DIR" ]
then
echo "Can't change to $LOG_DIR."
exit $E_XCD
fi
이제 터미널에서 sudo su를 실행하고 $UID를 에코하여 0을 제공합니다. 즉, 내 if 조건이 거짓으로 판명되었지만 여전히 "이 스크립트를 실행하려면 루트여야 합니다."라는 메시지가 표시됩니다. 이 스크립트를 실행하는 동안.
또한 원본 스크립트에서는 if 조건이 다음과 같이 제공되었습니다.
if [ "$UID" -ne "$ROOT_UID" ]
하지만 -ne은 문자열에만 사용되기 때문에 잘못된 숫자 오류가 발생하여 !=로 변경했습니다.
답변1
그것을 실행하는 대신
sh script.sh
그것을 실행
bash script.sh
(또는 #!/bin/bash
인터프리터를 설정하려면 첫 번째 줄에 추가하세요)
우분투의 쉘 sh
은~ 아니다 bash
이지만 dash
. dash
에는 처럼 많은 기능이 없으므로 bash
더 효율적이지만 이러한 누락된 기능으로 인해 에서 의도된 스크립트가 중단되는 경우가 있습니다 bash
. 그러한 특징 중 하나는 $UID
변수입니다.정의되지 않음안에 dash
.
즉 dash
, 스크립트가 에서 실행될 때 비교는 가 되며 ["" != "0"]
, 어떤 사용자가 이를 실행하든 상관없이 true로 평가됩니다. 그러나 루트 권한으로 실행하면 bash
문자열이 동일하고 스크립트가 작동합니다.
답변2
처럼맥 로빈 라고, 자동으로 설정된 읽기 전용 UID
(및 EUID
) 변수는 의 특수 기능입니다.bash
(그리고 다른 껍질들). 에 대한 표준이 아닙니다.본 스타일 쉘sh
이러한 변수를 설정한다고 가정할 수는 없습니다 . 특히 sh
우분투에서는 (현재 기본적으로)dash
, 이는 설정되지 않습니다.
두 가지 옵션이 있습니다:
bash
대신에 스크립트가 실행되도록 하세요sh
.- 이식성이 뛰어나고
bash
.
다음을 사용하여 스크립트 실행bash
스크립트 이름을 알려주지 않았습니다(괜찮습니다). 내가 전화할게cleanup
, 이는 작업 중인 가이드에 있는 유사한 스크립트의 이름이기 때문입니다.
특히 저는~ 아니다그것을 다음과 같이 부릅니다 cleanup.sh
. 접미사를 사용하여 이름을 지정하는 것을 권장하지 않기 때문입니다 .sh
.
- 접미사
.sh
는sh
! - 대부분의 스크립트에는 접미사가 전혀 제공되지 않으며 또는 접미사가 있으면
.sh
파일.bash
이 "최상위" 스크립트가 아닌 "라이브러리"임을 암시하는 것으로 해석될 수도 있습니다. 즉,.
실제로 직접 실행되기보다는 다른 스크립트(예: 내장 스크립트)에서 제공되는 코드를 제공합니다 .
그러나 .sh
접미사를 포함해도 스크립트의 기술적인 동작에는 어떤 방식으로도 영향을 미치지 않습니다. 그렇게 하는 것과 관련된 기술적인 이점이나 단점은 없습니다.
을 추가하다해시뱅 라인스크립트의 첫 번째 줄에:#!/bin/bash
스크립트를 실행 가능하게 만드세요와 함께 .chmod +x cleanup
이제 할 수 있습니다스크립트를 실행하세요다음 명령을 실행하여:
./cleanup
, 현재 디렉터리에 있는 경우. (특히 교육, 탐색, 테스트, 재미 또는 기타 제한적이거나 일회성 사용을 위해 스크립팅하는 경우 이것이 아마도 가장 일반적인 방법일 것입니다.)/path/to/cleanup
, 일반적으로. 명령의 첫 번째 단어에 가 포함되어 있으면/
실행 파일의 경로로 해석됩니다. ( 현재 디렉토리를 의미하는./
것처럼 위 구문 의 이유입니다 .).
에 의해첫번째 단어내 말은 첫 번째 명령을 포함하지 않고 최대 명령을 의미합니다.이스케이프되지 않은space 또는 tab:
foo-bar/baz
은 의 첫 번째 단어이고foo-bar/baz qux
, 이전 공백은 백슬래시로 이스케이프되므로spam\ ham
는 의 첫 번째 단어입니다 .spam\ ham eggs
ham
cleanup
, 해당 디렉터리에 있는 경우PATH
(먼저 나열된 디렉터리에 동일한 이름의 실행 파일이 없고 다음으로 대체되지 않은 경우)쉘 내장,기능, 또는별명).
스크립트 여부에 관계없이cleanup
hashbang 줄이 있거나 #!...
그 줄이 말하는 내용이 있습니다.
sh cleanup
sh
여전히 통역사로 실행하려고 시도합니다 .bash cleanup
bash
여전히 통역사로 실행하려고 시도합니다 .
이러한 경우에는 실제로 인터프리터( sh
또는 bash
)를 실행하고 실행할 스크립트 이름을 인터프리터에 전달하기 때문입니다. 많은 프로그램은 명령줄에서 열 파일 이름을 허용하며 쉘은 이 규칙을 따릅니다 sh
.bash
스크립트를 이식 가능하게 만들기
스크립트를 이식 가능하게 만들고 싶다면 가장 간단한 방법은 $UID
전혀 사용하지 않고 대신 모든 Bourne 스타일 쉘에서 사용할 수 있는 일부 기능을 사용하는 것입니다.
일반적으로 사용자 ID를 확인하는 내장 셸 기능은 없습니다. 하지만 당신은 사용할 수 있습니다id
. 이것은 쉘 내장이 아닌 외부 프로그램이지만 다음과 같습니다.cat
그리고ls
, 그것이 존재할 것이라고 기대하는 것이 합리적입니다.
id
그 자체로는 많은 정보를 출력하지만 id -u
유효한 사용자 ID만 제공합니다.
따라서 대신 다음을 if [ "$UID" != "$ROOT_UID" ]
사용할 수 있습니다.
if [ "$(id -u)" != "$ROOT_UID" ]
기술적으로, 이것은 동일하지 않습니다. $UID
in은 bash
실제 사용자 ID를 제공하며 id -u
실제로 bash
는 ' 에 해당합니다 $EUID
. EUID가 아닌 UID를 정말로 원한다면 id -ru
.