Scripting is a very useful skill which will save any Sysadmin a lot of time. Who wants to go to every device in their environment and perform the same task over and over again? In this posting I will cover a few basics for those getting started in scripting.
When writing a script you want to be sure it is:
When you think about it; writing scripts is not all that different from developing software. You are writing a bit of code for the computer to interpret in order to complete a task. You script may or may not have anything visible on the screen, but same goes for software you may write.
The main difference between a script and a program is a script is interpreted and a program is compiled then executed. A script you can modify with a text editor, then run immediately. A program you must modify, re-compile, then re-run. You might even use the same languages when scripting vs programming. Other than this minor difference, they are really the same thing; so the same principles should apply when developing your scripts.
Throughout this article, I will use some Python code to give examples when applicable
Lets go through our bullet points:
Ensuring your script is readable is essential for both you and others who may need to understand or modify it later. Readable scripts facilitate easier troubleshooting and updates, especially as changes occur in your operational environment.
While an entire article could be dedicated to the nuances of creating readable scripts, a key starting point is to observe and learn from existing scripts. Take note of how experienced scripters format their code and organize their logic. This observation can provide valuable insights into what makes a script easy to understand and what complicates comprehension.
By applying these practices, you make your scripts more accessible not only to others but also to your future self, ensuring that maintenance and troubleshooting can be conducted more smoothly and efficiently.
Investing time in scripting can yield significant time savings, turning a task that might take days into one that takes just seconds. To maximize the return on this investment, it’s beneficial to write scripts with reusability in mind. This means crafting your script so it can be easily adapted for future tasks, which may be similar yet distinct.
Here are some strategies to enhance the reusability of your scripts:
Functions or subroutines are your best friends when it comes to building reusable scripts. By encapsulating specific functionalities into functions, you create modular blocks of code that can be easily lifted and shifted into new scripts as needed.
For example, imagine you have a script designed to delete files older than 5 days. Within this script, you might include a function to determine the age of the files. When you later decide to create a script to report on files of similar age without deleting them, you can reuse the same age-calculation function. This not only saves time but also maintains consistency across your scripts, reducing the likelihood of errors when rewriting similar logic.
Avoid hard-coding values directly into your scripts. Instead, use variables to represent these values. This approach offers flexibility and makes your scripts more adaptable to changes without extensive rewrites.
Continuing with the previous example, if you initially set your script to delete files older than 5 days using a hard-coded value, modifying this to accommodate a new requirement of 7 days would be cumbersome and error-prone. By using a variable to store the age threshold, you only need to update the variable’s value to change the script’s behavior. This change propagates through all parts of your script where the variable is used, streamlining updates and maintenance.
By focusing on these aspects of scripting, you not only make your life easier but also enhance the quality and longevity of your scripts. Whether you’re automating routine tasks or building complex systems, reusability should be a cornerstone of your scripting strategy.
Comments are a vital part of writing clear, maintainable scripts. They help you and others understand the purpose, logic, and flow of the code even months after it was originally written. Well-commented code is especially crucial in a collaborative environment or when you’re likely to revisit your own code after a long period. Here’s how to effectively integrate comments into your scripting.
Descriptive Comments: Before blocks of code, write comments that describe what the code does and why it’s necessary. This is helpful for blocks of code that perform specific functions.
# Check if the file exists before attempting to delete
if os.path.exists(file_path):
os.remove(file_path)
else:
print(f"No file found at {file_path}")
Inline Comments: Use inline comments sparingly to clarify complex lines of code or unusual solutions that are not immediately obvious.
x = y + z # Increment x by the sum of y and z for the next loop iteration
Function and Module Comments: At the beginning of every function or module, use comments to explain the purpose, inputs, outputs, and any side effects.
def delete_old_files(path, days=5):
"""
Delete files older than a specified number of days.
Parameters:
path (str): Directory path to search for files.
days (int): Number of days old a file must be to be deleted.
"""
TODO Comments: If you’re in the middle of working on a script and need to leave notes for future tasks, use TODO comments to highlight areas that need further development or attention.
TODO: Implement error handling for file access permissions
Avoid Obvious Comments: Don’t over-comment by stating the obvious. Comments should add value and provide insight, not just reiterate what the code clearly says.
# BAD: Set x to 1
x = 1
# GOOD: Initialize x with the starting value for the counter
x = 1
By adhering to these practices, you ensure that your scripts are not only functional but also understandable and maintainable. Remember, writing comments is not just about documenting what the code does; it’s about making the code accessible and easier to manage for anyone who might work on it after you.
When developing scripts, it’s crucial to implement error handling to ensure that your scripts can gracefully handle unexpected situations without crashing. Effective error handling can provide stability and reliability in automated tasks, especially in a production environment. Here’s how to approach error handling in your scripts:
Error handling refers to the process of anticipating, detecting, and responding to exceptions or errors in a script. Without proper error handling, scripts might fail in unpredictable ways, possibly causing more damage or downtime. By managing errors appropriately, you can ensure that your script either recovers from the error or fails safely.
Try-Catch Blocks: Most scripting languages support try-catch blocks, which allow you to “try” a block of code and “catch” any errors that occur within it. Here’s a simple example in Python:
try:
# Attempt to open a file
with open('config.txt', 'r') as file:
data = file.read()
except FileNotFoundError:
print("Error: File not found.")
except Exception as e:
print(f"An error occurred: {str(e)}")
In this example, if the file config.txt does not exist, the script catches the FileNotFoundError and handles it by printing a specific message. Any other exceptions are caught by the general Exception class.
Checking Return Values: Some functions return specific values or codes when they fail. You can check these values to determine if an error occurred:
cp /source/file.txt /dest/
if [ $? -ne 0 ]; then
echo "Failed to copy file."
fi
In this Bash script example, $? captures the exit status of the last command executed (cp). If the copy operation fails, it returns a non-zero status, triggering the error message.
Validating Preconditions: Before performing actions, validate that all necessary conditions are met. This could involve checking for the existence of files, the validity of inputs, or network connectivity:
import os
if not os.path.isfile('config.txt'):
print("Error: config.txt is missing.")
exit(1) # Exit the script with an error code
By integrating robust error handling into your scripts, you can build more resilient and reliable systems that minimize downtime and maintain productivity even when unexpected events occur.
Hopefully this article has been helpful to you. I have gone over a few basics to consider when you start scripting. In the future I will go more in-depth about the concepts. Be sure to check back to the site as I will be posting scripts for performing various tasks.