0

When I do

$ watch kubectl get pods

it works fine but on doing:

$ alias p0="kubectl get pods"
$ watch p0

gives an error: Every 2.0s: p0
sh: p0: command not found

It looks like watch is starting a subshell and the aliases in my current shell aren't visible to the subshell. I do have

$ shopt -s expand_aliases

at the very top of my .bashrc but it isn't helping.

Trying this with bash version 3.2.57 on Mac OS Mojave.

Update: Tried a few more things:

$  watch -n 0.1 "source ~/.bashrc; shopt; alias p0; p0"

still doesn't work.

cdable_vars     off
cdspell         off
checkhash       off
checkwinsize    off
cmdhist         on
compat31        off
dotglob         off
execfail        off
expand_aliases  on
extdebug        off
extglob         off
extquote        on
failglob        off
force_fignore   on
gnu_errfmt      off
histappend      on
histreedit      off
histverify      off
hostcomplete    on
huponexit       off
interactive_comments    on
lithist         off
login_shell     off
mailwarn        off
no_empty_cmd_completion off
nocaseglob      off
nocasematch     off
nullglob        off
progcomp        on
promptvars      on
restricted_shell        off
shift_verbose   off
sourcepath      on
xpg_echo        on
p0='kubectl get pods'   <--- HERE'S THE ALIAS
sh: p0: command not found  <--- STILL DOESN'T EXECUTE IT.
3

Aliases are not inherited by subshells. Functions may be exported but while this approach makes Bash inherit exported function(s) from Bash, watch will interfere, mainly because it spawns sh, not bash.

You have at least three options:

  1. Make p0 a script somewhere in $PATH, so watch can run it like any other executable. If done right, this will be very robust.

  2. Define a special alias for watch:

    alias watch='watch '
    

    Then this happens:

    If the last character of the alias value is a blank, then the next command word following the alias is also checked for alias expansion.

    source

    So watch p0 will work (but watch -n 4 p0 won't).

  3. Define an alias (or function, or script, whatever) for the whole command:

    alias wp0='watch kubectl get pods'
    

    and type just wp0.

  • Great answer @Kamil. Reg. your first answer, I could make it a script. However, I have hundreds of aliases collected over the years and making them individual scripts seems like a lot of work. – user674669 Mar 12 '19 at 6:40
  • 1
    +1 on yr 2nd point. Been using aliases for yrs w/o ever having come across that nugget. – Cbhihe Mar 12 '19 at 7:18
1
function watcha() {
    a=$(alias $1) # extract the cmd from the alias

    #remove = sign and first/last ' before executing thru watch
    watch $(echo $a | awk -F= '{print $2}'|sed 's/.$//'|sed 's/^.//') 
}

Now when I do

$ watcha p0

it does work as expected.

  • alias watcha='watch ' seems more robust and so much simpler. – Kamil Maciorowski Mar 13 '19 at 16:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.