이상한 점: 저는 springboot fat archive 웹서버를 시작하는 서비스를 만들었습니다. 제공하다:
#!/bin/bash
[Unit]
Description=JalouWeb
[Service]
Type=simple
WorkingDirectory=/opt/jaloucontrol
ExecStart=/bin/bash jalouweb.sh
TimeoutStartSec=0
RestartSec=60
Restart=always
SyslogIdentifier=jalouweb
[Install]
WantedBy=multi-user.target
jalouweb.sh:
#! /bin/sh
#
java -Duser.timezone=Europe/Berlin -Dfile.encoding=UTF-8 -jar jcweb-0.0.1-SNAPSHOT.jar
jalouweb.sh를 사용자로 시작하면 됩니다. sudo -i를 실행하고 jalouweb.sh를 루트로 시작합니다. 사용자와 루트 모두 성공적으로 java -version을 호출할 수 있습니다.
하지만 systemctl을 통해 서비스를 시작하면 다음과 같은 메시지가 나타납니다.
... jalouweb.sh: Zeile 3: java: Kommando nicht gefunden.(<- command not found)
... systemd[1]: jalouweb.service: Main process exited, code=exited, status=127/n/a
jalouweb.sh에 경로를 추가하면 다음과 같습니다.
/opt/openjdk17/bin/java -Duser.timezone=Europe/Berlin...
systemctl도 성공했습니다. 그런데 왜? Afaik 사용자 없이 서비스를 실행한다는 것은 루트로 실행한다는 의미입니다. 루트는 sh와 java를 직접 시작할 수 있습니다. systemctl에 명시적인 경로가 필요한 이유는 무엇입니까?
편집: 나는 wenshuo의 제안을 따랐습니다. 서비스가 성공적으로 실행되지만 tmplog 파일은 생성되지 않지만 Journalctl은 다음을 보여줍니다.
systemd[1]: Started JalouWeb.
jalouweb[11189]:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin > /tmp/tmplog
systemd[1]: jalouweb.service: Succeeded.
echo 명령이 실제로 올바르지 않은 것 같습니다. 그러나 핵심 정보는 다음과 같습니다. 비대화형 루트 경로에 java가 없습니다.
편집 2 @Stephane: 스크립트를 찾거나 실행하는 데 문제가 없습니다. 문제는 스크립트에서 호출된 Java를 찾을 수 없다는 것입니다. systemctl의 실행자에게 경로나 JAVA_HOME을 제공하는 방법을 알아내야 합니다.
답변1
bash some-path
어디some-path
/
다음과 같은 문자가 포함되어 있지 않습니다 .아니요사용. 상황이 더 나쁠지라도 이는 여러 다른 Korn 유사 쉘1 및 .
내장2 source
또는 많은 Bourne 유사 쉘 에 적용됩니다 bash
.
bash
이는 프로그래밍 언어의 인터프리터와 마찬가지로 Bash 프로그래밍 perl
언어의 인터프리터 입니다 Perl
.
bash /path/to/some/Bash/file
표준 입력의 코드가 아닌 주어진 파일의 Bash/Perl 코드를 perl /path/to/some/Perl/file
말하거나 해석하는 방법 bash
과 같습니다 .perl
예를 들어 다음과 같은 용도로 사용됩니다.
#! /bin/bash -
실행 후 시스템은 이를 파일의 내용 으로 변환 /bin/bash - path/to/the/file
하고 해석합니다.bash
그리고 실행 중이지만 실행되지는 않습니다./bin/bash some-path
systemd
bash
bash
구현하다 some-path
3, 단지 그것을 읽고 그 안의 Bash 코드를 해석합니다.
지금, 언제some-path
/
동작 변경 사항이 포함되어 있지 않습니다 bash
. bash
먼저 일반 경로로 해석되므로 여기서는 현재 작업 디렉터리에 상대적이지만 파일을 찾을 수 없는 경우 $PATH
일부 기본 검색 목록의 환경 변수(또는 설정되지 않은 경우)의 디렉터리 구성 요소에서 해당 파일을 찾습니다. ).
이 행동은허용하다POSIX에서는 필요하지 않지만 POSIX에서는실행 가능 파일그 과정에서 발견된 파일. Bash(최소 버전 5.2)는 POSIX 모드에서도 실행 불가능한 파일을 찾아 비규격으로 만들 수 있습니다.
bash
여기에서는 스크립트가 있는 디렉터리에서 스크립트를 해석해야 하며 다음을 수행해야 합니다.
WorkingDirectory=/path/to/that/dir
ExecStart=/bin/bash ./the-script
( ./
경로에 접두사 a가 포함되어 있는지 확인하고 /
어떤 $PATH
이유로 현재 작업 디렉토리가 누락된 경우 조회를 비활성화하십시오.)the-script
WorkingDirectory
지정하지 않으면 기본값은 시스템 /
서비스와 사용자의 홈 디렉터리입니다.
또는 스크립트의 전체 경로를 지정해야 합니다.
ExecStart=/bin/bash /path/to/that/dir/the-script
실행 파일을 들여쓰기 the-script
하고 해석하여 find 로 bash
찾은 경우 실행 권한( )이 있는 shebang이 있고 에 저장되어 있는지 $PATH
확인하세요 .#! /bin/bash -
chmod a+x
$PATH
systemd
그리고 다음을 사용하세요:
ExecStart=the-script
파일이 실행 가능하다면 확장자를 제거하는 것이 좋습니다 .sh
. 그렇지 않고 Bash 언어로 작성된 경우 .bash
대신 확장을 사용하는 것이 좋습니다. .sh
표준 구문이 아닌 경우 sh
오해의 소지가 있습니다 .
¹ 이것은 sh 또는 ksh 에뮬레이션에서 zsh의 경우이며, ksh가 이 버그 기능의 소스일 수 있습니다.
² .
이것은 실제로 특수 내장 기능의 경우 POSIX보다 더 나쁩니다.필요 /
- 적은 경로가 검색됩니다 $PATH
(그리고 현재 작업 디렉터리로 대체됩니다). 일부 셸에서는 요구 사항이 무시됩니다(POSIX 모드가 아닌 경우 bash 포함).
³ 여기에 있는 bash -c the-script
텍스트는 the-script
bash에 의해 인라인 셸 코드로 해석되어 간단한 명령으로 해석되므로 차이가 있습니다 $PATH
.실행 가능 파일이를 수행하는 명령(스크립트 또는 비스크립트)구현하다.
답변2
실행 파일을 찾기 위해 쉘은 $PATH
변수에 나열된 디렉토리를 검색합니다. $PATH
디렉터리의 경로 이름을 포함하면 실행 파일의 전체 경로 이름을 제공하지 않고도 해당 디렉터리에서 실행 파일을 호출할 수 있습니다 .
echo "$PATH"
셸에서 현재 경로 목록을 볼 수 있습니다 . 귀하의 경우에는 대화형 쉘에 사용하는 것과 다를 수 $PATH
있습니다 .systemctl
root
$PATH
다음 명령을 사용하여 에서 사용된 값을 볼 수 있습니다.systemctl
ExecStart=/bin/echo "$PATH" > /tmp/tmplog
... [Service]
유닛 파일의 섹션에 있습니다. $PATH
그러면 의 값이 에 기록 됩니다 /tmp/tmplog
.