Looping Shell Script Recipe
The following procedure creates and executes a looping script that executes a command with output to a file and a sleep in between each execution:
- If you're using SELinux security, then you'll have to place the
script into an allowed location. First, check SELinux status:
Example output:sestatus | grep "Current mode"$ sestatus | grep "Current mode" Current mode: enforcing- If the
sestatuscommand does not exist orCurrent modeis set to anything other thanenforcing, then you can place the new script anywhere; for example:cd /tmp/ - If SELinux is set to
enforcing, then place the new script into an allowed directory (may requirerootpermission); for example, a common such directory:cd /usr/local/bin/
- If the
- Create a file named
diagscript.shreplacing the command after theCHANGEMEcomment, and, if necessary, the sleep time and the output location instead of/tmp/:#!/bin/sh set -e # Change output directory if needed outputfile="/tmp/diag_$(hostname)_$(date +"%Y%m%d_%H%M%S").txt" while true; do echo "[$(date)] Executing iteration" >> "${outputfile}" 2>&1 # CHANGEME: Change the `ps -elfyww` command to your desired command (but make sure to still write to ${outputfile}): ps -elfyww >> "${outputfile}" 2>&1 # Change the sleep time (in seconds) as needed: sleep 30 done - Manually confirm the looped command exists and works (as some
distributions support different flags). Using the example command above:
ps -elfyww - Make the script executable:
chmod +x diagscript.sh - If SELinux is set to
enforcing, change the security context of the script based on a well-known executable; for example:chcon --reference=/usr/bin/cat diagscript.sh - Check if you're running in a
systemdenvironment:systemctl status- If
systemctl statussucceeds (running in asystemdenvironment), start the script withsystemd-runso that it's not interrupted if the user that started the script logs out:
Example output:systemd-run ./diagscript.sh
Confirm the script is running by runningRunning as unit: run-r973b3f9d949b4d60a6b9a5fc842b84d1.service; invocation ID: 800d52ff3cb541659df667804ae7b149systemctl statuson the dynamically generated unit name and confirm it'sactive (running); for example:# systemctl status run-r973b3f9d949b4d60a6b9a5fc842b84d1.service [...] Active: active (running) since Tue 2025-01-14 08:41:28 CST; 54s ago Main PID: 2686 (diagscript.sh) - If
systemctldoes not exist (not running in asystemdenvironment), start the script withnohupso that it's not interrupted if the user that started the script logs out and send it to the background with&:nohup ./diagscript.sh &
- If
- If you'd like to watch the script output, you may
tailit (replacing/tmp/if you used a different directory):tail -f /tmp/diag*txt - Monitor that the script output does not exhaust disk
- When you are ready to stop the script:
- If the script was started with
systemd-run, stop it using the dynamically generated service name printed when starting it (or search insystemctl statusoutput); for example:systemctl stop run-r973b3f9d949b4d60a6b9a5fc842b84d1.service - If the script was started with
nohup, kill it by finding the process ID:
Alternatively, if available, usekill ${PID}pkillwith the script name:pkill -f diagscript.sh
- If the script was started with
- Upload
diag*txtand any other relevant logs