Reputation: 8507
I would like to use an alias command in bash in combination with the watch command. The watch command is multiple chained commands.
A very simple example how I would think it would work (but it does not):
alias foo=some_command # a more complicated command
watch -n 1 "$(foo) | grep bar" # foo is not interpreted as the alias :(
Upvotes: 17
Views: 7760
Reputation: 44
I made a function that uses the --color
option and allows you to use -n
to specify a refresh interval.
swatch_usage() {
cat <<EOF >&2
NAME
swatch - execute a program periodically with "watch". Supports aliases.
SYNOPSIS
swatch [options] command
OPTIONS
-n, --interval seconds (default: 1)
Specify update interval. The command will not allow quicker than 0.1 second interval.
EOF
}
swatch() {
if [ $# -eq 0 ]; then
swatch_usage
return 1
fi
seconds=1
case "$1" in
-n)
seconds="$2"
args=${*:3}
;;
-h)
swatch_usage
;;
*)
seconds=1
args=${*:1}
;;
esac
watch --color -n "$seconds" --exec bash -ic "$args || true"
}
I only needed color and timing support but i'm sure you could add more if you wanted.
The meat of the function is that it executes your command with bash directly in interactive mode and can thus use any aliases or commands that are normally available to you in bash.
I'm not that experienced with scripting so fair warning, your mileage may vary. Sometimes i have to press Ctrl+C
a few times to get it to stop, but for what it's worth, i've been using it frequently for 6 months without issue.
Gist form: https://gist.github.com/ablacklama/550420c597f9599cf804d57dd6aad131
Upvotes: 1
Reputation: 27360
watch -n 1 "$(foo) | grep sh"
is wrong for two reasons.
When watch "$(cmdA) | cmdB"
is executed by the shell, $(cmdA)
gets expanded before running watch
. Then watch
would execute the output of cmdA
as a command (which should fail in most cases) and pipe the output of that to cmdB
. You probably meant watch 'cmdA | cmdB'
.
The alias foo
is defined in the current shell only. watch
is not a built-in command and therefore has to execute its command in another shell which does not know the alias foo
. There is a small trick presented in this answer, however we have to make some adjustments to make it work with pipes and options
alias foo=some_command
alias watch='watch -n 1 ' # trailing space treats next word as an alias
watch foo '| grep sh'
Note that the options for watch
have to be specified inside the watch
alias. The trailing space causes only the next word to be treated as an alias. With watch -n 1 foo
bash would try to expand -n
as an alias, but not foo
.
Upvotes: 20