]> Execute permission on chained shell scripts through Azure DevOps 🌐:aligrant.com

Execute permission on chained shell scripts through Azure DevOps

Alastair Grant | Wednesday 20 April 2022

One thing is quite common when it comes to DevOps and cloud - a lot of scripting.   I'm not the greatest fan of scripting because unlike a lot of programming things doing tie up nicely and it's very, very easy to make rookie mistakes and thus velocity of productivity is greatly reduced - but here we are.

I recently have been deploying to Azure through Azure DevOps Services.  Microsoft make this very easy for you by providing the 'az' command line utility and components for orchestrating that through an Azure Pipeline.  The az command, like many things will run on multiple platforms (Windows and Linux), and with Windows Subsystem for Linux (WSL), it's possible to run Bash scripts natively even on a Windows Agent - but care needs to be taken with line endings.

I got to the point where I was running through a standard process:

  1. Build pipeline to package everything and validate
  2. Release pipeline to manage releases into multiple environments

The release process included the running of a Bash shell script, which in turn called another.  But when chained script was executed there was a "Permission denied" error.  For the uninformed, what makes a Bash script executable is the execute bit on the file system, which is standard for POSIX systems like Linux.  When on Linux, we do this by running the command chmod +x myfile.  Whereas in Windows there is no real concept of marking a file executable, it's indicated by the extension.

And here lay my first problem.  How do you mark a script as executable if you're developing in Windows?  As I'm using a git repository, you can do it with this command:

git update-index --chmod=+x myscript.sh

You can then commit that and push to your server.

I still was receiving this error though.  It's worth pointing out that it was only the nested/chained file that was failing to execute, the main shell script I defined in the pipeline was running without problem.  And that's because the pipeline will take care of making that file executable through it's own process, but once you're into the shell script you're within the usual rules of Bash.

With a bit of debugging I found that none of my files had the executable bit set at the release pipeline.  And this came down to the build process.  Despite running my build agent on Linux, the files that are output by an Azure pipeline do not include filesystem permissions.  And this is the crux of the problem.  In order to work around this we need to way of capturing the file permissions before the upload, and that can simply be done by archiving the outputs with tar or zip and then extracting the outputs at the start of the release pipeline.

Once this was completed, I had the execute bit travelling all the way through the Windows development machine, build and release pipelines.

Breaking from the voyeuristic norms of the Internet, any comments can be made in private by contacting me.