В моем Ansible-скрипте есть команда, которая заменяет строку в файле. Команда отлично работает при запуске на моей машине. Однако, когда он запускается с моим ansible-скриптом, он говорит No such file or directory
. Дело в том, что файл ДЕЙСТВИТЕЛЬНО существует, и 'sed' ДЕЙСТВИТЕЛЬНО заменил эту строку. Итак, команда выполнена успешно, но все равно выдает ошибку? Кто-нибудь знает, что может быть причиной этого?
Ansible задача
- name: Update path in plotly package
become: true
shell:
cmd:
sed -e '2s/.*/DIR = "$( cd "$( /usr/bin/dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>\&1 \&\& pwd )"/' -i '' /plotly/app/venv/lib64/python3.9/site-packages/kaleido/executable/kaleido
Ошибка
TASK [packages/plotly : Replace line in plotly package] ********************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "sed -e '2s/.*/DIR=\"$( cd \"$( \/usr\/bin\/dirname \"${BASH_SOURCE[0]}\" )\" >\/dev\/null 2>\\&1 \\&\\& pwd )\"/' -i '' /plotly/app/venv/lib64/python3.9/site-packages/kaleido/executable/kaleido", "delta": "0:00:00.004789", "end": "2024-07-30 16:16:24.704142", "msg": "non-zero return code", "rc": 2, "start": "2024-07-30 16:16:24.699353", "stderr": "sed: can't read : No such file or directory", "stderr_lines": ["sed: can't read : No such file or directory"], "stdout": "", "stdout_lines": []}
@tink Обновлен вопрос с актуальной задачей.
И еще вопрос: ваша локальная машина — Mac? Поскольку синтаксис -i ''
не используется GNU sed, как в большинстве дистрибутивов Linux...
@tink Я запускаю его на RedHat 8, но вручную запускаю команду на своем Mac.
Избавьтесь от ''
, попробуйте просто -i
Проблема переносимости с помощью sed -i
рассматривается, например. в stackoverflow.com/questions/43171648/… но поскольку в самом Ansible есть лучшее решение, я не буду голосовать за закрытие его дубликата.
@tink Это исправило это для меня. Спасибо!
Рад это слышать... тем не менее: вам действительно следует использовать line-in-file
, как предложил U880D в их ответе... использование sed
не является тривиальным идемпотентом.
может быть вам нужен полный путь для отправки?
В вашем случае использования вместо этого рекомендуется использовать модуль lineinfile — Управление строками в текстовых файлах . Он менее подвержен ошибкам, имеет лучшую абстракцию и обработку ошибок, поддерживает check_mode , diff , изменен , имеет Safe_file_operations, может гарантировать идемпотентность и многое другое...
В любом случае, в системе RHEL для тестового файла типа
- This
- is
- a
- test.
менее рекомендуемый минимальный пример сборника сценариев
---
- hosts: localhost
become: false
gather_facts: false
tasks:
- shell:
cmd: |
sed --in-place '/ is/{
s// was/g
w /dev/stdout
}' /home/ansible/test.txt
register: result
changed_when: result.stdout_lines | length | int > 0
- debug:
var: result
приведет к выводу
TASK [shell] **********************************
changed: [localhost]
TASK [debug] **********************************
ok: [localhost] =>
result:
changed: true
cmd: |-
sed --in-place '/ is/{
s// was/g
w /dev/stdout
}' /home/ansible_user/test.txt
delta: '0:00:00.006268'
end: '2024-07-31 11:00:00.648871'
failed: false
msg: ''
rc: 0
start: '2024-07-31 11:00:00.642603'
stderr: ''
stderr_lines: []
stdout: '- was'
stdout_lines:
- '- was'
PLAY RECAP ***********************************
localhost : ok=2 changed=1
и измененный файл
- This
- was
- a
- test.
Второй запуск приведет к
TASK [shell] *********************************
ok: [localhost]
TASK [debug] *********************************
ok: [localhost] =>
result:
changed: false
...
PLAY RECAP ***********************************
localhost : ok=2 changed=0
Дальнейшее чтение
Вероятно, также нужно подумать о Как сообщить об изменениях sed --in-place? , а также Как напечатать номера строк, измененные sed?
Отличная информация, спасибо!
Пожалуйста, добавьте реальную задачу к вашему вопросу в виде блока кода. Одна только ошибка не так уж и важна.