Tentando copiar / colar scripts longos com vários EOFs, o Terminal começa a ser executado na metade do caminho

1

Estava tentando criar um bloco de texto que eu pudesse copiar e colar em uma janela do Terminal para realizar algo (neste caso, criar um script systemd para fazer manutenção no MySQL dbs, criar um arquivo temporizador para executar esse script semanalmente e para habilitar o script).

Ao colá-lo em um Terminal, ele exibe metade do script (até o primeiro EOF), solicita a senha por meio de leitura e, em seguida, copia a senha digitada, juntamente com o restante do script no local em que $ pass está no primeiro arquivo.

Este é o bloco:

sudo sync && echo 'Enter MySQL password for Maintenance user' && read pass && sudo bash -s -c 'cat > "/usr/lib/systemd/system/db-m.service"' << "EOF"
[Service]
Type=oneshot
ExecStart='/usr/bin/mysqlcheck' --auto-repair --optimize --all-databases --force -u'maintenance' -p'$pass'
ExecStart='/usr/bin/sync'
EOF
sudo bash -c 'cat > "/usr/lib/systemd/system/db-m.timer"' << EOF
[Unit]
Description=Weekly database repair and maintenance

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=timers.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable 'db-m.timer' && sudo systemctl start 'db-m' 'db-m.timer' && sudo systemctl status 'db-m' -l

Eu adicionei recentemente o "read pass" e a variável '$ pass' que ocorre 3 linhas depois; sem essas duas coisas, eu posso copiar e colar o bloco inteiro sem problemas.

    
por Espionage724 28.04.2016 / 17:27

1 resposta

0

O shell em execução no terminal recebe o script que você está colando na entrada padrão e o próprio script lê a partir da entrada padrão. Há um conflito aqui: seu script acabará lendo um pouco de si mesmo.

Se você não receber um prompt do sudo, o que acontece é:

  1. O shell lê linhas inteiras até que tenha um comando completo. A primeira linha inicia um documento aqui, então o shell continua lendo o documento aqui.
  2. Quando o shell atinge a primeira linha EOF , ele tem um comando completo, portanto, ele é executado.
  3. sudo sync e 'echo'… 'executado.
  4. read pass é executado. Ele lê uma linha de entrada, que é sudo bash -c … . Isso define pass .
  5. sudo sync é executado.
  6. O shell concluiu a execução dos comandos que leu, por isso lê a próxima linha de entrada que é [Unit] .

Não cole o código shell multilinha complexo em um terminal. Em vez disso, se você realmente precisar executar o conteúdo da área de transferência como um script de shell, use xsel ou xclip em X11 ou pbpaste no OSX.

eval "'xsel'"
eval "'xclip'"
eval "'pbpaste'"

Mas, na verdade, o que você deve fazer é colocar isso em um script, com #!/bin/sh no topo.

    
por 29.04.2016 / 00:46