여러 EOF가 포함된 긴 스크립트를 복사/붙여넣으려고 하면 터미널이 중간에 실행되기 시작합니다.

여러 EOF가 포함된 긴 스크립트를 복사/붙여넣으려고 하면 터미널이 중간에 실행되기 시작합니다.

뭔가를 하기 위해 터미널 창에 복사해서 붙여 넣을 수 있는 텍스트 블록을 만들려고 합니다. (이 경우에는 MySQL 데이터베이스 유지 관리를 위한 시스템 스크립트를 만들고, 매주 수행할 타이머 파일을 만듭니다. 스크립트를 작성하고 플레이북을 활성화합니다).

이것을 터미널에 붙여넣으면 스크립트의 절반(첫 번째 EOF까지)이 표시되고, 이를 읽어 비밀번호를 묻는 메시지가 표시되고, $pass가 첫 번째 파일에 있는 나머지 스크립트와 함께 입력된 비밀번호가 복사됩니다. .

이것은 블록입니다:

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

최근에 3줄 뒤에 나타나는 "read pass" 및 "$pass" 변수를 추가했는데, 이 두 가지가 없으면 문제 없이 전체 블록을 복사하고 붙여넣을 수 있습니다.

답변1

터미널에서 실행되는 쉘은 표준 입력에 붙여넣은 스크립트를 수신하고 스크립트 자체는 표준 입력에서 읽습니다. 여기에 충돌이 있습니다. 스크립트가 자체 콘텐츠 중 일부를 읽게 됩니다.

sudo 프롬프트가 수신되지 않으면 다음과 같은 상황이 발생합니다.

  1. 쉘은 완전한 명령을 얻을 때까지 전체 행을 읽습니다. 첫 번째 줄은 here 문서를 시작하므로 쉘은 here 문서를 계속 읽습니다.
  2. 쉘이 첫 번째 EOF라인에 도달하면 완전한 명령이 있으므로 이를 실행합니다.
  3. sudo sync그리고 "echo '..."를 실행하세요.
  4. read pass달리다. 입력 한 줄, 즉 sudo bash -c …this set 을 읽습니다 pass.
  5. sudo sync달리다.
  6. 셸은 읽은 명령 실행을 마쳤으므로 다음 입력 줄인 를 읽습니다 [Unit].

복잡한 여러 줄의 셸 코드를 터미널에 붙여넣지 마세요. 대신 클립보드 내용을 쉘 스크립트로 실행해야 한다면 다음을 사용하세요.셰르또는클립X11에서 또는pbpasteOSX에서.

eval "`xsel`"
eval "`xclip`"
eval "`pbpaste`"

하지만 실제로 해야 할 일은 이를 스크립트에 넣는 것입니다.#!/bin/sh상단에.

관련 정보