다른 사용자로 스크립트 시작


12

나는 /etc/init.d/에 스크립트를 만들었는데 마치 마치 마치 홈 디렉토리의 다른 (루트가 아닌 권한있는) 사용자가 시작한 것처럼 다른 스크립트를 실행해야합니다.

이 스크립트를 다음과 같이 시작합니다. sudo -b -u <username> <script_of_a_particular_user>

그리고 작동합니다. 그러나 계속 실행되는 모든 사용자 스크립트 (예 : 일부 감시)에 대해 해당 부모 sudo 프로세스가 여전히 살아 있고 루트로 실행되는 것을 볼 수 있습니다. 활성 프로세스 목록에 혼란이 발생합니다.

그래서 내 질문은 : 기존 bash 스크립트에서 다른 사용자로 다른 스크립트를 시작하고 분리하여 분리 된 프로세스로 남겨 둘 수 있습니까?

더 자세한 설명 :
기본적으로 시스템의 다른 사용자에게 .startUp 및 .shutDown이라는 홈 디렉토리에있는 각 하위 디렉토리에있는 실행 파일을 실행하여 시스템 시작 또는 시스템 종료시 물건을 실행할 수있는 수단을 제공하려고합니다. 내가 할 수있는 다른 방법을 찾지 못했기 때문에 정확히 그것을 수행하는 bash 스크립트를 작성하고 /etc/init.d/에서 서비스 스크립트로 (스켈레톤 예제를 따라) 구성했습니다. start 인수를 사용하면 .startUp 디렉토리에서 모든 것을 시작하고 stop 인수로 실행하면 모든 사용자의 .shutDown 디렉토리에서 모든 것을 시작합니다.

또는이 문제를 해결하기 위해 기존 솔루션을 사용할 수 있다면 관심이 있습니다.

업데이트
조금 둘러 보았고이 질문을 찾았습니다 : /unix/22478/detach-a-daemon-using-sudo

거기에 허용되는 대답은 다음을 사용 sudo -u user sh -c "daemon & disown %1"하는 것입니다. 그러나 나는 또한 % 1을 제거 하지 않고 시도했지만 동일합니다. 그래서 이것이 내가 예상 한대로 작동합니다.

sudo -u <username> bash -c "<script_of_a_particular_user> &"

내 추가 질문은 지금 왜 불명예하지 않고 작동합니까? 특별한 경우에 관계없이 불허 전화를 떠나야 합니까?

업데이트 2

분명히 이것은 작동합니다.

su <username> -c "<script_of_a_particular_user> &"

이 호출과 sudo 호출간에 차이가 있습니까? 나는 이것이 완전히 다른 질문이라는 것을 알고 있습니다. 그러나 내가이 주제를 위해 아마도 여기에서 답을 찾고 있기 때문에 누군가가 이것을 분명히 할 수 있습니다.

업데이트 3
su 또는 sudo를 사용하는 두 가지 방법 모두 시스템을 부팅 한 후 새로운 startpar 프로세스 (루트로 실행되는 단일 프로세스)를 생성합니다 . 프로세스 목록에 다음과 같이 표시됩니다.

startpar -f -- <name_of_my_init.d_script>

이 프로세스가 생성되는 이유는 무엇입니까? 분명히 다른 init.d 스크립트 에서이 프로세스를 실행하지 않기 때문에 뭔가 잘못하고 있습니다.

업데이트 4
startpar 관련 문제가 해결되었습니다. 나는 그것에 대한 또 다른 질문을 시작했다 :
rc.local 또는 init.d에서 프로세스를 시작할 때 startpar 프로세스가 정지 상태로 남았습니다.

또한 권한이없는 사용자를위한 시작 메커니즘에 대한 추가 질문 :
초기화 및 종료 자동 실행 기능이있는 일반 사용자 (비 루트) 제공

답변:


18

이에 대한 정답은 올바른 "데몬 화"를 위해 표준 입력, 표준 출력 및 표준 오류를 / dev / null (또는 실제 파일)로 리디렉션해야한다는 것입니다.

su someuser -c "nohup some_script.sh >/dev/null 2>&1 &"

SU -에 대체 사용자 ID 결과 someuser의
-c - SU 인수는 지정된 명령을 실행하려면
nohup을을 - 실행 정지하지에 명령 면역. 부모 프로세스가 자식 프로세스를 종료하는 경우를 방지합니다. 만약을 위해 여기에 추가했습니다. 그러나 실제로 내 특별한 경우에는 효과가 없습니다. 필요한지 여부는 환경에 따라 다릅니다 (check shopt )
> / dev / null- 기본 출력을 아무것도 비활성화하고 기본적으로 비활성화합니다.
2> 및 1 - 널 리디렉션 표준 오차로 재 표준 출력 (1), (2) 출력
- 배경 분리,이 행 / 디바이스 / 널 또한 표준 입력을 리디렉션한다.

이것은 본질적으로 데비안 dpkg의 start-stop-daemon 유틸리티 가 핵심에서하는 것과 정확히 같습니다 . 그렇기 때문에이 방법으로 스크립트를 시작하는 대신 코드에 다른 외부 유틸리티 호출을 도입하는 것이 좋습니다. start-stop-daemon시작 해야하는 전체 데몬 프로그램이 있고 start-stop-daemon이 제공 하는 추가 기능이 필요한 경우 (예 : 지정된 프로세스가 이미 실행 중인지 확인하는 경우 )에 유용 합니다. 다시 시작하지 마십시오).

프로세스의 파일 디스크립터를 / dev / null 로 리디렉션하는 대신 파일 디스크립터를 닫을 수도 있습니다 .

su someuser -c "some_script.sh 0<&- 1>&- 2>&- &"

0 <&- 표준 입력 닫기 (0)
1> &- 표준 출력 닫기 (1)
2> &- 표준 오류 닫기 (2) 출력

긴 파일 디스크립터 번호가 지정되므로 <> 부호의 방향은 중요하지 않습니다. 따라서 이것은 똑같이 좋습니다.

su someuser -c "some_script.sh 0>&- 1>&- 2>&- &"

또는

su someuser -c "some_script.sh 0<&- 1<&- 2<&- &"

그러나 방향을 중요하게 여기는 stdin 및 stdout에 대한 숫자없이 작성하는 조금 더 짧은 방법이 있습니다.

su someuser -c "some_script.sh <&- >&- 2>&- &" 

파일 디스크립터가 닫히거나 / dev / null로 경로 재 지정 될 때 ( start-stop-daemon 이 / dev / null로 경로 재 지정을 수행함) 프로세스는 백그라운드에서 디먼으로 실행하는 것이 안전합니다. 부팅시 스크립트 실행과 관련된 문제 ( startpar ) 를 피하기 위해 필요한 것입니다 .

초기 아이디어에서 전체 솔루션을 구현하고 GitHub에 배치했습니다 :
https://github.com/ivankovacevic/userspaceServices


Ivan, su 또는 su-login을 사용하는 것이 더 낫습니까? 나는 su의 사람을 읽었지만이 특정한 경우에 대해 이해할 수 없습니다.
Massimo

1
@Massimo, 답변이 늦어 져 죄송합니다. 이 질문을 확인하십시오 : unix.stackexchange.com/questions/318572/… 더 나은 매뉴얼 페이지가 있습니다. 기본적으로 차이점은 작업 디렉토리 및 환경 변수 설정에 있습니다. 이와 같은 유스 케이스 (다른 사용자로 무언가 수행)에 대해서는 실제로 -login을 사용하는 것이 좋습니다.
Ivan Kovacevic

3

옵션 으로 init.d 에서 start-stop-daemon을 사용할 수 있습니다 --user.


나는 Shark 씨의 답변에 대한 시작-중지-데몬에 대해 언급했으며, 또한 나의 답변과 나의 질문 (업데이트 4)을 업데이트했습니다
Ivan Kovacevic

2

나는 이것을 완전히 테스트하지는 않았지만 다음과 같이 생각합니다.

/sbin/start-stop-daemon --background --start --exec /home/USER/.startUp --user USER --pidfile=/home/USER/.startUp.pid --make-pidfile

시작할 때

/sbin/start-stop-daemon --stop --user USER --pidfile=/home/USER/.startUp.pid

종료 할 때.

.shutDown 스크립트 처리는 시작과 같은 방법으로 수행 할 수 있지만 종료가 발생하기 때문에 스크립트가 종료되도록 확신 할 수 없습니다 :-)

트릭을 수행해야 할 수도 있습니다. 아마도 일부 입력 리디렉션을 던져야하지만 로그 파일이 채워지는 것에 대해 걱정해야합니다.


2
본질적으로 이것은 작동합니다! start-stop-daemon은 부팅시 또는 그렇지 않으면 프로세스를 성공적으로 시작할 수 있습니다. 나는 그것을 테스트했습니다. 또한 startpar 프로세스를 중단시키는 문제를 제거합니다. 그러나 시작 호출에 --chuid USER도 없습니다. 그렇지 않으면 루트로 프로세스를 시작합니다. pid 파일은 / var / run /에도 작성해야합니다. 그렇지 않으면 사용자 홈 디렉토리에 루트 소유 파일이 생성되기 때문입니다. 그러나 제 생각에는 일반 스크립트 시작의 경우 start-stop-daemon은 약간 과잉입니다. 이유를 자세히 설명하려는 답을 확인하십시오.
Ivan Kovacevic

1

를 사용해 보셨습니까 su?

su -c /home/user/.startUp/executable - user

-c su에게 명령을 실행하도록 지시하고 마지막 매개 변수는 사용자가 명령을 실행하는 것입니다.


예, 그것은 작동하지만 약간의 인용과 앰퍼샌드가 추가되었습니다. su <username> -c "/some/path/script.sh &"기본적으로 sudo는 더 깨끗해 보이지만 sudo를 사용했지만 더 나은 것 같습니다. sudo- u <username> bash -c "/some/path/script.sh &". 그래도이 두 가지에 차이가 있는지 모르겠다
Ivan Kovacevic
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.