9 Ideas For Higher Scripting Expertise



Throughout my day after day work, I’ve needed to do numerous scripting. This could vary from operating brief assessments in Docker containers to operating tremendous lengthy processes in Azure Batch service. I’ve used Bash and Python for these functions and discovered fairly a number of helpful strategies alongside the best way. I’m sharing them right here in hopes that they could prevent a while and also you don’t need to study them the “exhausting” method.

The following pointers should not organized in any explicit ordering. Sit again, chill out and skim on ?

Tip 1: Enhance terminal historical past

Generally throughout your experimentation, you notice that the command you ran yesterday was working however you forgot what parameters you handed to it. You remind your self that you would be able to all the time press the up arrow key within the terminal to return to that command. However when you begin urgent the up key you notice that you’ve run a gazillion instructions since then. So that you attempt to do a recursive lookup of the command utilizing Ctrl + r however it doesn’t present up. That is if you find yourself reminded that the default command historical past in Ubuntu (and I’m assuming different Linux distros) is 1000 strains. You possibly can improve this depend to an even bigger quantity by placing this in your ~/.bashrc:


You possibly can study concerning the completely different between these two variables in this StackOverflow reply.

Tip 2: Print the arguments to display

Oftentimes, you can see your self making use of atmosphere variables. Someday your script works and the subsequent day it breaks. You begin debugging what went improper however you possibly can’t appear to determine the basis trigger. You resolve to return and see what arguments you handed to your script however oh boy you used atmosphere variables and you aren’t positive what worth these variables had once you ran the script. That is once you notice that you need to have printed out the worth of these variables on the display in order that you could possibly see them in case you break your script.

This tip helped me immensely not too long ago. I used to be engaged on a Python script and was spending some instructions to a distant system. One of many instructions seemed one thing like this:

cmd = "docker login -u `echo $DOCKER_USERNAME` -p `echo $DOCKER_PASS`"

I wasn’t organising the atmosphere variables and this command was failing with entry denied error. Once I printed the worth of DOCKER_USERNAME on display I noticed that there was a typo. If I had solely printed the instructions on display from the start I’d have been in a position to determine the problem instantly.

Tip 3: Print execution time

You realize that the script you might be engaged on goes to take a while to execute. You run the script within the background and go for a espresso break. You come again and the script nonetheless hasn’t terminated. You ask your self how lengthy the script has been operating for however you don’t know the reply since you forgot so as to add time to your output.

That is so widespread that I’ve determined to make it a behavior so as to add timing operate to my script. In Python I take advantage of one thing much like this:

import time

def timestamped_print(msg: str):
    print(f'[{time.asctime(time.gmtime())}] {msg}')

Then I exchange a daily print with timestamped_print. It produces an output much like this:

>>> timestamped_print("hello there!")
[Thu Jun 11 19:09:09 2020] hello there!

You can even configure your terminal to print the present time as a part of the immediate.

Utilizing a logger might be higher however once you wish to go much more bare-bones then that is tremendous helpful.

Tip 4: Save the script output

Generally you can see your self engaged on a system the place a one-line change in your script modified some a part of the output. You don’t pay an excessive amount of consideration to what strains within the output change so long as the script continues working. Then you definately introduce a second change to the script and half the output is right and half is improper.

You attempt scrolling again to the output of the preliminary run of your script however quickly discover out that it was a day in the past and you may’t scroll again that far anymore. This teaches you the significance fo piping the output of your script to a file through the growth section. It’s tremendous straightforward to do:

$ command &> output.txt

However you say “hey! I wish to see the output within the terminal as effectively!” and I say “use tee“:

$ command | tee /path/to/file

tee prints the output to display and pipes it to a file.

Please be aware that in a earlier tip I like to recommend you print the parameters and atmosphere variables on the display when operating a script. Ensure you don’t save any of these to a file which will probably be model managed. We don’t need your secrets and techniques leaking in git historical past.

Tip 5: Hold your scripts in model management

You’ll be iterating in your previous scripts and will probably be repeatedly tweaking them. Generally you’ll make a tweak and notice that your change broke the whole lot and a easy ctrl+z isn’t taking you that far again in historical past. At this level, you notice how essential it’s to maintain your scripts beneath model management. You’ll really feel quite a bit braver whereas making adjustments to your scripts now.

I choose to maintain my script on GitHub in a non-public repo. You get limitless personal repos so I don’t know why you wouldn’t have your scripts beneath model management and in a non-public repo.

You can even put your atmosphere variables in a file referred to as .env after which put that in your .gitignore. This manner you possibly can hold your essential variables in a single place with out placing them in model management.

Tip 6: Catalogue your experiments

You begin writing a script considering that you can be completed after a few minutes. A few minutes later you improve your estimate to a few hours and earlier than you realize it you’ve gotten spent greater than a day engaged on the identical script. You have a look at the folder you might be working in and you’ve got a bunch of recordsdata with tremendous descriptive names:

$ ls 
app.py script.py works.py new_try.py

You notice that you simply not know what the completely different recordsdata are. That is the place you study a few essential classes:

  • It is best to have named your recordsdata a bit higher
  • It is best to have saved a log of what every file does

The largest piece of recommendation is to all the time work in your initiatives in a method the place even when you need to come again after a yr, you can also make sense of what’s going on. This implies two issues:

  • Give your recordsdata a extra descriptive identify. It may cost a little you an additional millisecond to sort the identify proper now however it is going to prevent from numerous complications down the highway.
  • If you happen to for some motive have to have a number of recordsdata with an analogous identify a minimum of write down what every file does in a easy readme.md file.

Tip 7: Use tmux for SSH

You’re engaged on a distant server and you might be related utilizing SSH. All of a sudden your connection drops and a long-running script terminated due to that. You have a look at your self within the mirror, cry a bit, after which search on-line about methods to forestall an analogous situation from occurring once more.

You come throughout tmux. You acknowledge that it has a slight studying curve however it’s going to prevent from numerous related crappy conditions sooner or later. It could take a while getting used to it however you promise your self that you’ll spend a while studying it.

Psst. You can even script tmux in order that it opens up and runs predefined instructions. You possibly can learn extra about it in this text by Martin.

Tip 8: Use -E to go atmosphere variables to sudo

Generally you’ll want to go in atmosphere variables to your scripts. You export the variable within the present bash window and the script works advantageous:

$ export VARIABLE=hello
$ python3
>>> import os
>>> os.environ['VARIABLE']

However then you definately run your script utilizing sudo and the script breaks.

$ sudo python3
>>> import os
>>> os.environ['VARIABLE']
Traceback (most up-to-date name final):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/os.py", line 675, in __getitem__
    increase KeyError(key) from None
KeyError: 'VARIABLE'

Your first intuition is to make use of sudo export VARIABLE=hello however you get an error:

$ sudo export VARIABLE=hello
sudo: export: command not discovered

Then you definately curse and attain out to Google and discover out concerning the -E flag for sudo. You append that proper after sudo and all of a sudden your script begins working once more:

$ sudo -E python3
>>> import os
>>> os.environ['VARIABLE']

The -E flag tells sudo to protect the atmosphere variables when switching to sudo. Tremendous helpful once you wish to run a script utilizing sudo and nonetheless have entry to the atmosphere variables.

Tip 9: Print useful error messages

You write a 100+ line script with none errors on the primary attempt. Then you definately modify the script barely and all of a sudden it begins to error out. It doesn’t print any useful error messages. You solely print a msg when the script begins operating and when it stops execution. You bang your head towards the wall and query your selections. If solely you had added ample logging proper from the start you’ll have been in a position to determine the error supply fairly simply.

There are a number of methods so as to add logging to your scripts. In Python, you need to use the logging module. It gives you easy however highly effective choices. You possibly can study extra about methods to use it from the official tutorial. You can even make a decorator to log operate calls. There are one million methods to do logging. The one factor that issues is that you simply truly do it.

Time for a enjoyable annecdote. I used to be operating instructions on a distant machine. Theses instructions have been in an inventory and seemed one thing like this:

instructions = [
    'sudo apt-get update',
    'sudo apt-get install docker.io'
    'echo "Done!"'

Do you see something improper with that record? I forgot a , on the finish of the second record merchandise! Python interpreted the second merchandise as sudo apt-get set up docker.ioecho "completed!". This was clearly improper however it took me one million years to determine what was taking place.

This isn’t an exhaustive record. I discovered the following pointers by engaged on a number of scripts. If you happen to discovered this text helpful please share it with different individuals. When you’ve got your individual suggestions that you simply wish to add then be happy to place them within the feedback under and/or submit a pull request on GitHub. You’ll find the GitHub supply by clicking on the “supply” button proper subsequent to the title.

I’ll see you guys later ? ❤️