A ZDM host tends to get used in short, frequent bursts — check if the service is up, check a job’s status, tail a log, confirm a wallet credential exists — usually while something else is waiting on the outcome. Typing full zdmcli/zdmservice invocations every time adds friction that’s easy to eliminate with a properly built .bash_profile. This one is built around three things: an always-visible service status in the prompt, one-word shortcuts for the commands used constantly, and functions for the ones used occasionally but painfully without them.
The Full Profile
# ~/.bash_profile — zdmuser
# ------------------------------------------------------------------
# ZDM environment
# ------------------------------------------------------------------
export ZDM_BASE=/u01/zdm/zdmbase
export ZDM_HOME=/u01/zdm/zdmhome
export PATH=$PATH:$ZDM_HOME/bin:$HOME/.local/bin
export EDITOR=vim
export LESS='-R -M -i -j5'
export HISTSIZE=5000
export HISTFILESIZE=10000
export HISTTIMEFORMAT="%F %T "
export HISTCONTROL=ignoredups:erasedups
# ------------------------------------------------------------------
# Colors
# ------------------------------------------------------------------
C_RESET='\[\033[0m\]'
C_GREEN='\[\033[1;32m\]'
C_RED='\[\033[1;31m\]'
C_YELLOW='\[\033[1;33m\]'
C_BLUE='\[\033[1;34m\]'
C_GREY='\[\033[0;37m\]'
# ------------------------------------------------------------------
# ZDM-aware prompt
# Shows RUNNING/STOPPED status inline, colored, without a manual check
# ------------------------------------------------------------------
zdm_prompt_status() {
local status
status=$($ZDM_HOME/bin/zdmservice status 2>/dev/null | awk '/Running:/{print $2}')
if [ "$status" = "true" ]; then
echo -e "\033[1;32mZDM-UP\033[0m"
else
echo -e "\033[1;31mZDM-DOWN\033[0m"
fi
}
export PROMPT_COMMAND='PS1_ZDM=$(zdm_prompt_status)'
PS1="${C_BLUE}\u@\h${C_RESET} [\${PS1_ZDM}${C_RESET}] ${C_YELLOW}\w${C_RESET} \n\$ "
# ------------------------------------------------------------------
# One-word shortcuts for constant commands
# ------------------------------------------------------------------
alias zstatus='$ZDM_HOME/bin/zdmservice status'
alias zversion='$ZDM_HOME/bin/zdmcli -build'
alias zjobs='$ZDM_HOME/bin/zdmcli query job'
alias zhome='cd $ZDM_HOME'
alias zbase='cd $ZDM_BASE'
alias zlogs='cd $ZDM_BASE/crsdata/$(hostname -s)/zdmsvc/log'
alias ll='ls -lAh --color=auto'
alias rm='rm -i'
# ------------------------------------------------------------------
# Functions for the occasional-but-painful commands
# ------------------------------------------------------------------
# Full detail on a specific job, e.g.: zjob 42
zjob() {
if [ -z "$1" ]; then
echo "usage: zjob <job_id>"
return 1
fi
$ZDM_HOME/bin/zdmcli query job -jobid "$1"
}
# Tail the most recently modified ZDM log file
ztail() {
local latest
latest=$(find "$ZDM_BASE/crsdata/$(hostname -s)/zdmsvc/log" -type f -name '*.log' \
-printf '%T@ %p\n' 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2-)
if [ -z "$latest" ]; then
echo "No log files found under ZDM_BASE/crsdata log directory."
return 1
fi
echo "==> $latest"
tail -f "$latest"
}
# List which wallets exist and whether each has a stored credential
zwallets() {
local w
for w in "$ZDM_BASE"/wallets/*/; do
[ -d "$w" ] || continue
local name count
name=$(basename "$w")
count=$($ZDM_HOME/bin/mkstore -wrl "$w" -listCredential 2>/dev/null | grep -c '^1')
if [ "$count" -ge 1 ]; then
echo -e " ${name}\t\033[1;32mcredential stored\033[0m"
else
echo -e " ${name}\t\033[1;31mempty\033[0m"
fi
done
}
# Watch a running job's status refresh every 5 seconds until it finishes
zwatch() {
if [ -z "$1" ]; then
echo "usage: zwatch <job_id>"
return 1
fi
watch -n 5 "$ZDM_HOME/bin/zdmcli query job -jobid $1"
}
# ------------------------------------------------------------------
# Login banner
# ------------------------------------------------------------------
if [ -t 1 ]; then
echo ""
echo -e "\033[1;34m========================================================\033[0m"
echo -e " ZDM Host : $(hostname -s)"
echo -e " ZDM_HOME : $ZDM_HOME"
echo -e " Service : $(zdm_prompt_status)"
ver=$($ZDM_HOME/bin/zdmcli -build 2>/dev/null | grep 'patch version' | cut -d'"' -f2)
echo -e " Patch ver : ${ver:-unknown}"
echo -e "\033[1;34m========================================================\033[0m"
echo ""
fi
Walking Through the Interesting Parts
The status-aware prompt
zdm_prompt_status calls zdmservice status and greps the Running: line, and PROMPT_COMMAND re-runs it before every prompt is drawn. The result: every prompt shows ZDM-UP in green or ZDM-DOWN in red without ever having to remember to check. This has a real cost — one extra process spawn per prompt — which is a non-issue on an interactive ZDM host but worth knowing if you ever adapt this pattern for something with much tighter prompt-latency requirements.
Shortcuts vs. functions
The split here is deliberate: plain alias for anything that’s always the exact same command (zstatus, zversion, zjobs), and a function for anything that needs an argument or does more than one thing (zjob <id>, zwatch <id>, ztail). Aliases can’t take positional parameters cleanly, so reaching for a function the moment you need $1 avoids a whole category of “why doesn’t this alias work” confusion later.
ztail finds the log for you
Rather than remembering (or looking up) the exact log filename pattern under ZDM_BASE/crsdata/<host>/zdmsvc/log, ztail finds the most recently modified .log file in that tree and follows it. During an active migration job this is almost always the file you actually want, without having to ls -lt first.
zwallets turns a multi-command check into one glance
Checking whether every wallet from the wallet setup guide actually has a credential stored means running mkstore -listCredential once per wallet and reading the output each time. zwallets loops every directory under $ZDM_BASE/wallets and prints a green “credential stored” or red “empty” per wallet — useful right after initial setup, and just as useful months later when confirming a rotated password actually landed.
The login banner
Purely cosmetic, but genuinely useful on a shared ZDM host: the moment you SSH in, you know the hostname, ZDM_HOME, whether the service is up, and the current patch version — the same three things you’d otherwise run three separate commands to confirm.
Installing It
# as zdmuser
cp .bash_profile ~/.bash_profile.bak # keep the existing one, just in case
vi ~/.bash_profile # paste in the profile above
source ~/.bash_profile
What Login Looks Like
========================================================
ZDM Host : zdmhost01
ZDM_HOME : /u01/zdm/zdmhome
Service : ZDM-UP
Patch ver : 21.6.3
========================================================
zdmuser@zdmhost01 [ZDM-UP] ~
$ zjobs
Summary
None of these functions do anything zdmcli or zdmservice couldn’t already do directly — the value is entirely in removing the friction of remembering exact syntax and log paths during the kind of quick, repeated checks that happen constantly around a migration window. A prompt that already tells you the service is down saves the one debugging step everyone forgets to do first.