Linux AWK system Function: Execute Shell Commands
The system function in awk allows you to execute shell commands within awk
.
This tutorial will introduce you to the awk
system function.
You’ll learn how to execute shell commands within awk
, manage input to avoid security vulnerabilities, and dynamically construct commands to handle a wide range of tasks.
Basic Syntax and Usage
Here’s a basic example:
awk 'BEGIN { system("date") }'
Output:
Sat Mar 30 15:20:49 UTC 2024
This command uses awk
to execute the date
command in the shell.
The BEGIN
block runs before processing any lines of a file.
Execute Single and Multiple Commands
Execute a Single Command
Suppose you want to check the disk usage of your system, you can use the df
command within awk
. Here’s how:
awk 'BEGIN { system("df -h") }'
Output:
Filesystem Size Used Avail Use% Mounted on tmpfs 388M 1.7M 387M 1% /run /dev/sda1 217G 9.8G 196G 5% / tmpfs 1.9G 0 1.9G 0% /dev/shm tmpfs 5.0M 4.0K 5.0M 1% /run/lock /dev/sda4 266G 3.4M 253G 1% /home tmpfs 388M 100K 388M 1% /run/user/1000
Execute Multiple Commands
When you need to execute multiple commands, you can chain them using a semicolon (;
).
For example, to list the current directory contents and display the current date, you can use:
awk 'BEGIN { system("ls; date") }'
Output:
file1.txt file2.txt data.txt Sat Mar 30 15:45:32 UTC 2024
Return Values and Exit Status
When you use the awk
system function, it returns the exit status of the command it executes.
This status is a numeric value, typically 0
for success and a non-zero value for failure.
awk 'BEGIN { exit_status = system("ls non_existent_file"); print "Exit Status:", exit_status }'
Output:
ls: cannot access 'non_existent_file': No such file or directory Exit Status: 2
This output shows that attempting to list a non-existent file results in an error and an exit status of 2
which means a failure.
Handle Multiple Commands
When executing multiple commands, the system function returns the exit status of the last command executed.
awk 'BEGIN { exit_status = system("echo Hello; false"); print "Exit Status:", exit_status }'
Output:
Hello Exit Status: 1
Even though the first command (echo Hello
) succeeds, the exit status reflects the failure of the second command (false
, which always returns a non-zero exit status).
Using Exit Statuses in Scripts
You can check the exit status if it was successful or not:
awk '{ exit_status = system("ping -c 1 example.com"); if (exit_status == 0) system("echo Ping successful"); else system("echo Ping failed"); }'
Output:
PING example.com (93.184.216.34) 56(84) bytes of data. 64 bytes from 93.184.216.34: icmp_seq=1 ttl=56 time=11.3 ms --- example.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 11.311/11.311/11.311/0.000 ms Ping successful
In this script, awk
runs a ping command and then decides which message to print based on the success (exit status 0
) or failure of the ping.
Dynamically Constructing Shell Commands
Dynamically constructing commands means that the command string is built during the execution of the script, often based on variable content or runtime conditions.
Assume you want to dynamically construct a command to create a directory with a name based on a variable:
awk 'BEGIN { dirName = "backup_" strftime("%Y-%m-%d") cmd = "mkdir " dirName system(cmd) }'
In this script, awk
constructs a command to create a directory. The directory name includes the current date to ensure a unique folder name each time the script runs.
Moving to a more advanced example, suppose you want to dynamically construct a command based on file contents.
For instance, reading from a file and taking actions based on its content:
awk '{ if ($1 == "CREATE") { cmd = "touch " $2 system(cmd) } else if ($1 == "DELETE") { cmd = "rm " $2 system(cmd) } }' commands.txt
Assuming commands.txt
contains lines like CREATE file1.txt
and DELETE file2.txt
, this script will create or delete files accordingly.
This script reads commands from commands.txt
and executes them.
Avoid Command Injection Vulnerabilities
Command injection is a security vulnerability that allows an attacker to execute arbitrary commands on a host operating system.
These vulnerabilities can occur when untrusted input is used to construct shell commands
The first line of defense against command injection is to validate and sanitize any external input used in your scripts.
Suppose your awk
script takes user input to create a directory.
Here’s how you can validate the input:
awk '{ dirName = $0 if (dirName ~ /^[a-zA-Z0-9_]+$/) { cmd = "mkdir " dirName system(cmd) } else { print "Invalid directory name" } }' <<< "$userInput"
Output:
Invalid directory name
In this script, the regular expression ^[a-zA-Z0-9_]+$
ensures that the directory name contains only letters, numbers, and underscores.
When you try any other input, it will return the error message shown above.
Mokhtar is the founder of LikeGeeks.com. He is a seasoned technologist and accomplished author, with expertise in Linux system administration and Python development. Since 2010, Mokhtar has built an impressive career, transitioning from system administration to Python development in 2015. His work spans large corporations to freelance clients around the globe. Alongside his technical work, Mokhtar has authored some insightful books in his field. Known for his innovative solutions, meticulous attention to detail, and high-quality work, Mokhtar continually seeks new challenges within the dynamic field of technology.