Today I learned: the difference between echo vs printf in bash scripting.
TLDR: printf is more portable and most likely preferable over using echo.
The back story: I’m currently working on my devops skills by hand rolling a ci/cd pipeline.
My requirements are that I want a pre-commit hook which checks linting, formatting, and test. A nice to have is recovery. If code is changed from linting/formatting I would like for the new changes to be patched into the commit. After committing I would like to push to gh and run lint format and test again.(most likely the duplication is not needed but I want to avoid the “it works on my machine” problem) After the steps are verified on the remote repo, I would like an automated push to prod where the 3 steps are run one more time before resetting my process. I would like to use bash scripting as much as possible to help with reusability.
Why hand-roll?: There are alot of services/toolings that make hand rolling unnecessary, but it’s an abstraction over the fundamental problem of delivery. I find it useful for learning to do things the “wrong/unconventional” way to have a better appreciation of why we use certain services/tooling. It’s also helpful to have a deep knowledge so that when evaluating alternative options, one can make a better informed decisions.
Why Bash?: Simply put, it’s the standard. For most cloud services, the operating system of choice is linux. I work on a unix device (MacOS). By leveraging bash I can avoid duplicating my effort across 3 environment’s. Earlier this year I made an attempt to use alternative shell’s (specifically nu shell). What I learned in that experience was that I didn’t do a proper deep dive on bash. For the foreseeable future I plan to use zsh/bash as my shell environment so that I can run into the quirky edge cases. Perhaps in the future I may switch to an alternative shell but only time will tell. As an aside, this is not the first time that I’ve played around with bash scripting. Because of previous work I was able to assist one of our previous clients in improving their ci/cd pipeline. They wanted to enhance their gh actions pipeline to tag versions of their releases. Knowing bash in advance was helpful in resolving that task. This is because gh actions may run on a linux environment.
Bringing it all together: I’m in the early stages of my pipeline but I wanted to create a function to confirm my actions. I used an llm to help me write the function and the result I got for displaying a message was echo -n “Proceed? [y/n]: " This was providing a leading -n to my prompt message. Poking at the llm a bit more I was able to learn about printf. After learning about the 2 different ways for outputting to stdout, I began reading documentation as well as searching the internet to better understand the difference between the 2 options. I learned that echo is used for simple message where as printf could be used for formatting. From what I could tell on the internet, its also more portable between environments. More research is needed but this resonates with me because my device is zsh whereas environments I deploy to are bash. This is my current iteration of my confirm function.
confirm () {
local msg=$1
printf "${msg} [y/n]: "
read -rn 1 ans
if [[ "$ans" == "y" ]]; then
return 0
fi
# If not 'yes', return 1
return 1
}
In the medium/long term I’m hoping to build a collection of simple bash utility functions that I can reuse for different projects. Thanks for listening to my ted talk!!!