Permission denied: calling a shell script from Python in a Jenkins job

Question:

Trying to provide the minimal amount of information necessary here, so I’ve left a lot out. Lots of similar questions around, but the most common answer (use chmod +x) isn’t working for me.

I have a Python script and a shell script that sit next to each in a GitHub Enterprise repository:

enter image description here

Next, in Jenkins I check the code in this repository out. The two key steps in my Jenkinsfile are like so:

dir ("$WORK/python")
{           
    sh "chmod +x test.sh"
    sh "python3 foo.py -t '${AUTH}'"
}

Here, $WORK is the location on the Jenkins node that the code checks out to, and python (yes, poorly named) is the folder in the repository that the Python and shell script live in. Now, foo.py calls the shell script in this way:

try:
    cmd = f'test.sh {repo_name}'
    subprocess.Popen(cmd.split())

except Exception as e:
    print(f'Error during repository scan: {e}')  

Here, repo_name is just an argument that I define above this snippet, that I’m asking the shell script to do something with. When I run the job in Jenkins, it technically executes without error, but the exception branch above does run:

11:37:24  Error during repository scan - [Errno 13] Permission denied: 'test.sh'

I wanted to be sure that the chmod in the Jenkinsfile was running, so I opened a terminal to the machine that the code checked out to and found that the execute permissions were indeed correctly set:

-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

I’ve gone around on this most of the day. What the heck is going on?

Asked By: Pat Jones

||

Answers:

Doing this fixed it:

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

cmd = f'{BASE_DIR}/test.sh {repo_name}'
Popen(cmd.split())

Why? In my ignorance associated with picking up someone else’s code, I neglected to see, buried further up before the call to the shell script, that we change to a folder one level down:

os.chdir('repo_content')

The shell script does not, of course, live there. So calling it without specifying the path won’t work. I’m not sure why this results in [Errno 13] Permission denied: 'test.sh', as that would imply that the shell script was found, but fully qualifying the path as above is doing exactly what I had hoped.

Answered By: Pat Jones
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.