Como usar quote e dollarsign com systemd

7

Estou usando isso em uma declaração de serviço: ExecStartPre=/usr/bin/docker pull "$DOCKER_USERNAME/redis-replication:latest"

No log do systemd, posso ver isso quando tento iniciar o serviço:

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

Parece que o systemd não executou o comando adequado, mas algum estranho. O que poderia ser e como corrigir isso?

Editado : Aqui está todo o meu arquivo de unidade

[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"
    
por Phương Nguyễn 21.12.2014 / 17:35

2 respostas

7

Depois de algumas pesquisas, descobri que não há problema em usar aspas na definição do ExecStart de um arquivo de serviço systemd. Quanto ao uso da variável shell, é necessário usar chaves para esclarecer onde o nome da variável termina quando os caracteres não espaciais estiverem conectados à própria variável.

No caso acima, o sistema deve ter tratado $DOCKER_USERNAME/redis como o nome da variável em vez de $DOCKER_USERNAME . Adicione chaves e, em seguida, interprete-as corretamente.

Editar : Mais informações sobre o que a sintaxe é ok com o systemd podem ser encontradas aqui: link

Basicamente, a maioria das notações de shell está ok, com exceção dos operadores de pipe.

    
por 22.12.2014 / 04:56
0

Acabei de me esforçar para citar e executar a seguinte linha de comando na chave ExecStart de um arquivo de unidade de serviço:

IFS=$'\n'; f=($(ls $HOME/bk.d/DuckieTV*.backup | tail -n +2)); echo "${f[@]}"

Vou citá-lo usando as regras de cotação do systemd e depois explicarei o que aprendi no processo. Parece complicado porque esperamos que ele siga as regras de cotação de shells POSIX, mas na verdade é ainda mais simples. Aqui está a diretiva ExecStart , devidamente citada

ExecStart=/bin/bash -c 'IFS=$$\'\n\'; f=($$(ls ${HOME}/bk.d/DuckieTV*.backup | tail -n +2)); echo \"$${f[@]}\"'

ou

ExecStart=/bin/bash -c "IFS=$$\'\n\'; f=($$(ls ${HOME}/bk.d/DuckieTV*.backup | tail -n +2)); echo \"$${f[@]}\""

Então, as regras de cotação:

  1. Inclua a sequência a ser tratada como um único argumento entre aspas simples ( '' ) ou aspas duplas ( "" ). Eles são tratados da mesma forma, não importa qual você escolher, desde que a cotação de fechamento seja a mesma da cotação de abertura
  2. Analise a sequência da esquerda para a direita, substituindo ' por \' , " por \" e $ com $$

Se você quiser que o systemd faça substituições de variáveis, então não cite $ , mas o systemd não trata $ var e $ {var} como o mesmo. Ambos são substituídos pelo valor de ambiente de var , mas a divisão de palavras será diferente em cada caso: com $ var , após a substituição do valor de var , as palavras serão divididas em espaço em branco, enquanto que com $ {var} não haverá divisão de palavras. Efetivamente, o systemd trata $ var como um shell POSIX faria, mas trata $ {var} como um shell POSIX trataria "$ var" .

    
por 14.05.2018 / 21:54

Tags