특정 디렉터리에서 임의의 명령을 실행할 수 있는 명령이 있나요?
데비안 10에서는 간단히 사용할 수 있습니다env --chdir
. 그러나 env --chdir
Debian 9 설치에서는 사용할 수 없습니다.
내가 실행하려는 명령의 일부는 공백이나 기타 특수 문자를 포함할 수 있는 셸 변수로 구성됩니다. 예를 들어, 내가 실행하려는 명령이 다음과 같다고 가정해 보겠습니다.
strace -- "$@"
따라서 다음은 작동하지 않습니다.
sudo -i sh -c 'cd my-directory && exec strace -- "$@"'
어, 왜 이러는 거죠?
sudo -i
/를 사용하여 sudo --login
명령을 실행하고 싶습니다 . 하지만 루트 사용자의 홈 디렉터리가 아닌 특정 디렉터리에서 명령을 실행하고 싶습니다. 환경 변수를 설정할 수는 있지만 sudo
디렉터리를 변경하는 옵션은 없는 것 같습니다.
나는 다음과 같은 이유로 이를 사용합니다 sudo -i
: 1) 내가 실행 중인 프로그램(내 Ansible 플레이북)에 가 있기를 원합니다 HOME=/root
. 그러면 프로그램이 내 홈 디렉토리에 루트 소유 파일을 생성하는 것을 방지할 수 있습니다. 2) 이것은 완전히 새로운 환경이 내 문제를 해결하는 가장 원칙적인 방법처럼 들립니다 sudo
.-i
답변1
이러한 질문에 대한 귀하의 요구 사항이 무엇인지 명확하지 않기 때문에 exec
무시 하겠습니다 .-i
그러나 cd
그때 sudo
까지
( cd «a directory»; sudo «a command» )
괄호는 내장된 ()
하위 쉘을 생성한 다음 명령 등을 생성합니다. 따라서 프로세스 수는 와 같습니다 . 또한 환경 변수를 조작하므로 필요 하지 않을 수도 있습니다 .cd
sudo
env
sudo
env
sudo
답변2
다음과 같은 별도의 스크립트를 쉽게 작성할 수 있습니다 chdir
.
#!/bin/sh
dir=$1 &&
shift &&
cd -- "$dir" &&
exec "$@"
별도의 스크립트가 없으면 훨씬 더 모호해집니다.
sh -c 'cd -- "$1" && shift && exec "$@"' sh my-directory "$@"
그러나 이것은 질문에 설명된 실제 목표를 달성하지 못합니다. 위의 스크립트를 사용하여 실행할 수 있다고 생각할 수도 있습니다 sudo --login chdir my-directory ...
. 이것은 대부분의 경우에 효과가 있을 수 있지만, 나는 그것이 나쁜 생각이라고 생각합니다. 보고 man sudo
:
-i
,--login
대상 사용자의 비밀번호 데이터베이스 항목에 지정된 쉘을 로그인 쉘로 실행합니다. 이는 쉘이 .profile, .bash_profile 또는 .login과 같은 로그인별 리소스 파일을 읽는다는 것을 의미합니다. 명령이 지정되면
-c
쉘의 옵션을 통해 실행할 수 있도록 쉘에 전달됩니다.
sh -c
단일 문자열 인수를 사용합니다. 따라서 이것이 얼마나 잘 작동하는지는 sudo
사용자 쉘의 인용 규칙과 얼마나 잘 일치하는지에 따라 달라집니다. 쉘 따옴표는 끔찍합니다.
실제로 이것을 시도해 보면 다음과 같습니다.무엇이상한 일이 일어날 수 있습니다. 다른 사람들의 분석에 따르면 이 인용문은 sudo
"놀라움" 또는 "무서움"일 수 있습니다. 바라보다:"sudo --login"에서 "sh -c"를 실행하면 위치 매개변수가 확장되지 않습니다. 해결책이 있나요?
이것이 나의 진정한 목표를 달성하는 또 다른 방법입니다. 별도의 스크립트 파일을 만들 필요는 없지만 이를 쉘 함수로 멋지게 래핑할 수 있습니다.
run_as_root() {
sudo --set-home \
bash -l \
-c 'exec "$@"' \
bash \
"$@"
}
설명하다:
sudo --set-home
- 다른 사용자로 명령을 실행합니다. 일부 환경은 변경되었지만 일부 환경은 그대로 유지되었습니다.HOME
새로운 사용자의 홈 디렉토리가 되도록 강제됩니다 .bash -l
- "로그인 셸"을 실행하여 환경을 초기화합니다. 이는root
사용자가 다른 쉘을 사용하도록 사용자 정의되지 않았다고 가정합니다bash
.bash -c 'inline shell script' arg0 arg1 arg2...
- 작은 쉘 스크립트를 실행하십시오.$0
로 설정됨arg0
,$1
로 설정됨arg1
등 주목은$0
특별합니다. 쉘은$0
그것을 자신의 이름으로 취급합니다. 쉘이 오류 메시지를 인쇄할 때 오류 메시지는$0:
. 그러므로arg0
로 설정해야 합니다bash
.exec
- 쉘 프로세스를 다른 프로그램으로 교체합니다."$@"
- 확장"$1" "$2" ...