systemd에서 따옴표와 달러 기호를 사용하는 방법

systemd에서 따옴표와 달러 기호를 사용하는 방법

나는 이것을 서비스 선언에 사용합니다.

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[@]}\""

따라서 인용 규칙은 다음과 같습니다.

  1. 단일 매개변수로 처리될 문자열을 작은따옴표로 묶습니다('') 또는 큰따옴표(" "). 종가가 시가와 동일하다면 어느 것을 선택하든 모두 동일하게 취급됩니다.
  2. 문자열을 왼쪽에서 오른쪽으로 스캔하고 교체합니다.'그리고\',"그리고\"그리고$그리고$$

systemd에서 변수 대체를 수행하려면 인용하지 마십시오.$, 그러나 systemd는 처리하지 않습니다$var그리고${var}같은. 모두 환경 값으로 대체됩니다.변하기 쉬운, 그러나 단어 분할은 각 경우에 따라 다릅니다.$var, 대체된 값변하기 쉬운, 단어는 공백으로 분할되지만${var}단어 분할은 없습니다. 실제로 systemd 핸들$varPOSIX 쉘과 비슷하지만 다음을 처리합니다.${var}POSIX 쉘로서"$var".

관련 정보