디렉토리를 변경한 다음 명령을 연결(`exec`)하시겠습니까? [복사]

디렉토리를 변경한 다음 명령을 연결(`exec`)하시겠습니까? [복사]

특정 디렉터리에서 임의의 명령을 실행할 수 있는 명령이 있나요?

데비안 10에서는 간단히 사용할 수 있습니다env --chdir. 그러나 env --chdirDebian 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» )

괄호는 내장된 ()하위 쉘을 생성한 다음 명령 등을 생성합니다. 따라서 프로세스 수는 와 같습니다 . 또한 환경 변수를 조작하므로 필요 하지 않을 수도 있습니다 .cdsudoenvsudoenvsudo

답변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" ...

관련 정보