나는 이것을 서비스 선언에 사용합니다.
ExecStartPre=/usr/bin/docker pull "$DOCKER_USERNAME/redis-replication:latest"
서비스를 시작하려고 하면 systemd 로그에서 다음을 볼 수 있습니다.
Usage: docker pull [OPTIONS] NAME[:TAG]
Pull an image or a repository from the registry
-a, --all-tags=false Download all tagged images in the repository
systemd가 올바른 명령을 실행하지 않고 이상한 명령을 실행하는 것 같습니다. 무엇이 될 수 있으며 어떻게 수정합니까?
편집됨:이것은 내 전체 유닛 파일입니다.
[Unit]
Description=Run redis replication
After=docker.service
Requires=docker.service
[Service]
Restart=always
RestartSec=10s
EnvironmentFile=/etc/vax/credentials
EnvironmentFile=/etc/vax/centos-ip
EnvironmentFile=/etc/vax/docker-auth
EnvironmentFile=/etc/vax/cluster-prefix
ExecStartPre=-/usr/bin/docker kill redisrep
ExecStartPre=-/usr/bin/docker rm redisrep
ExecStartPre=/usr/bin/docker pull "$DOCKER_USERNAME/redis-replication:latest"
ExecStart=/usr/bin/docker run --rm --name redisrep -v /var/data/myproject/redis:/data -e S3_ACCESS_KEY=$S3_ACCESS_KEY -e S3_SECRET_KEY=$S3_SECRET_KEY -e S3_BUCKET=$S3_BUCKET -e BACKUP_PREFIX=$BACKUP_PREFIX -e REPLICATE_FROM_IP=$CENTOS_IP -e REPLICATE_FROM_PORT=6379 $DOCKER_USERNAME/redis-replication:latest
ExecStop=/usr/bin/docker kill redisrep
[X-Fleet]
MachineMetadata="machineIndex=1"
답변1
몇 가지 조사 끝에 systemd 서비스 파일의 ExecStart 정의에 따옴표를 사용해도 괜찮다는 사실을 발견했습니다. 쉘 변수를 사용하는 경우 공백이 아닌 문자가 변수 자체에 연결되는 경우 중괄호를 사용하여 변수 이름이 끝나는 위치를 명확하게 해야 합니다.
위의 경우 시스템은 $DOCKER_USERNAME/redis
대신 변수 이름을 처리해야 합니다 $DOCKER_USERNAME
. 중괄호를 추가하면 올바르게 설명됩니다.
편집하다: systemd에서 사용할 수 있는 구문에 대한 자세한 내용은 여기에서 확인할 수 있습니다.http://www.freedesktop.org/software/systemd/man/systemd.service.html#Command%20lines
기본적으로 파이프 연산자를 제외하고 대부분의 쉘 표기법은 괜찮습니다.
답변2
ExecStart
서비스 단위 파일의 키를 참조하고 다음 명령줄을 실행하는 데 어려움을 겪었습니다.
IFS=$'\n'; f=($(ls $HOME/bk.d/DuckieTV*.backup | tail -n +2)); echo "${f[@]}"
시스템화된 인용 규칙을 사용하여 이를 참조한 다음, 그 과정에서 배운 내용을 설명하겠습니다. POSIX 쉘의 인용 규칙을 따르기 때문에 복잡해 보이지만 실제로는 더 간단합니다. 이것은 ExecStart
올바르게 인용된 지시문 입니다.
ExecStart=/bin/bash -c 'IFS=$$\'\\n\'; f=($$(ls ${HOME}/bk.d/DuckieTV*.backup | tail -n +2)); echo \"$${f[@]}\"'
또는
ExecStart=/bin/bash -c "IFS=$$\'\\n\'; f=($$(ls ${HOME}/bk.d/DuckieTV*.backup | tail -n +2)); echo \"$${f[@]}\""
따라서 인용 규칙은 다음과 같습니다.
- 단일 매개변수로 처리될 문자열을 작은따옴표로 묶습니다('') 또는 큰따옴표(" "). 종가가 시가와 동일하다면 어느 것을 선택하든 모두 동일하게 취급됩니다.
- 문자열을 왼쪽에서 오른쪽으로 스캔하고 교체합니다.'그리고\',"그리고\"그리고$그리고$$
systemd에서 변수 대체를 수행하려면 인용하지 마십시오.$, 그러나 systemd는 처리하지 않습니다$var그리고${var}같은. 모두 환경 값으로 대체됩니다.변하기 쉬운, 그러나 단어 분할은 각 경우에 따라 다릅니다.$var, 대체된 값변하기 쉬운, 단어는 공백으로 분할되지만${var}단어 분할은 없습니다. 실제로 systemd 핸들$varPOSIX 쉘과 비슷하지만 다음을 처리합니다.${var}POSIX 쉘로서"$var".