Пытаясь предоставить минимальное количество информации, необходимой здесь, поэтому я многое упустил. Много похожих вопросов, но самый распространенный ответ (используйте chmod +x
) мне не подходит.
У меня есть скрипт Python и скрипт оболочки, которые находятся рядом с каждым в репозитории GitHub Enterprise:
Затем в Jenkins я проверяю код в этом репозитории. Два ключевых шага в моем файле Jenkins выглядят так:
dir ("$WORK/python")
{
sh "chmod +x test.sh"
sh "python3 foo.py -t '${AUTH}'"
}
Здесь $WORK
— это расположение на узле Jenkins, в которое проверяется код, а python
(да, плохое название) — это папка в репозитории, в которой живут Python и сценарий оболочки. Теперь foo.py
вызывает сценарий оболочки таким образом. :
try:
cmd = f'test.sh {repo_name}'
subprocess.Popen(cmd.split())
except Exception as e:
print(f'Error during repository scan: {e}')
Здесь repo_name
— это просто аргумент, который я определяю над этим фрагментом, с которым я прошу сценарий оболочки что-то сделать. Когда я запускаю задание в Jenkins, оно технически выполняется без ошибок, но ветвь исключений выше выполняется:
11:37:24 Error during repository scan - [Errno 13] Permission denied: 'test.sh'
Я хотел убедиться, что chmod
в файле Jenkins работает, поэтому я открыл терминал на машине, на которой был проверен код, и обнаружил, что разрешения на выполнение действительно установлены правильно:
-rw-r--r-- 1 adm domain users 4106 Feb 6 14:24 foo.py
-rwxr-xr-x 1 adm domain users 619 Feb 6 14:37 test.sh
Я занимался этим большую часть дня. Что же такое происходит?
Я уже использую #!/usr/bin/python3
в верхней части моего файла Python, а также #!/bin/bash
в верхней части моего сценария оболочки, поэтому я не думаю, что это связано с этим.
Попробуйте использовать /bin/bash test.sh
(или любой другой подходящий интерпретатор) в своем подпроцессе. Единственное, что я действительно могу придумать, что позволит запускать скрипт python, но не скрипт bash, это если в вашей системе есть какая-то утилита белого списка.
Также, возможно, проверьте, что родительские каталоги являются исполняемыми для пользователя, выполняющего это задание, и что каталог не находится в точке монтирования с noexec (проверьте с помощью findmnt -T .
). Основное различие между вашими двумя программами заключается в том, что вы полагаетесь на то, что скрипт python будет доступен для чтения python3
, но вы полагаетесь на то, что скрипт bash является исполняемым файлом, поэтому любые внешние блокираторы выполнения разрешат скрипт python, но не баш скрипт.
Достаточно интересно, если я выполняю test.sh
вручную в терминале узла, после того, как задание Jenkins попыталось запустить его, я получаю успешное выполнение. Мы используем сценарии оболочки в других местах нашей кодовой базы, поэтому я склонен думать, что это не проблема на уровне машины, как noexec
.
Давайте продолжим обсуждение в чате.
@ tjm3772 - Все разрешения для родительского каталога выглядят хорошо. findmnt
показывает некоторые подкаталоги в /sys
, в которых есть noexec
, но каталоги, важные для работы, в порядке. Если я сделаю /bin/bash test.sh
в вызове подпроцесса, результат на выходе консоли будет 14:12:52 /bin/bash: test.sh: No such file or directory
.
Выполнение этого исправило это:
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
cmd = f'{BASE_DIR}/test.sh {repo_name}'
Popen(cmd.split())
Почему? По своему невежеству, связанному с подбором чужого кода, я забыл увидеть, закопанное выше, перед вызовом сценария оболочки, что мы переходим в папку на уровень ниже:
os.chdir('repo_content')
Сценарий оболочки, конечно, там не живет. Поэтому вызов без указания пути не сработает. Я не уверен, почему это приводит к [Errno 13] Permission denied: 'test.sh'
, так как это будет означать, что сценарий оболочки был найден, но полное указание пути, как указано выше, делает именно то, на что я надеялся.
добавьте
#!/usr/bin/python
в первую строку вашего исходного кода, или, если вы используете python 2.7, вы можете добавить#!/usr/bin/python2.7