patchThe GNU Bourne-Again SHell - Patches: patch #9723, Alias definitions not recognized...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

patch #9723: Alias definitions not recognized in an if-block

Submitter:  Martin Anantharaman <manantharaman>
Submitted:  Thu 15 Nov 2018 09:18:49 AM UTC
   
 
Category:  None Priority:  5 - Normal
Status:  Invalid Privacy:  Public
Assigned to:  None Open/Closed:  Open

Jump to the original submission

Fri 16 Nov 2018 04:04:23 PM UTC, comment #6: 

That's succinct and to the point. I would elaborate a bit more:

The rules concerning the definition and use of aliases are somewhat confusing. Essentially an alias command needs to have been executed before code using it is parsed. Further, keep in mind that bash always reads and parses at least one complete line of input (which may include several commands including alias commands), but also any number of lines that make up a compound command (including function-definitions), before executing any of the commands. Overlooking this will lead to "command not found" errors at points of use within a complex command even after the alias definition.

Martin Anantharaman <manantharaman>
Fri 16 Nov 2018 02:27:56 PM UTC, comment #5: 

Well, there's the updated version. Maybe that will be better from your perspective:

The  rules  concerning  the  definition and use of aliases are somewhat
       confusing.  Bash always reads at least one complete line of input,  and
       all  lines that make up a compound command, before executing any of the
       commands on that line or the compound command.

Chet Ramey <chet>
Group administrator
Fri 16 Nov 2018 01:15:07 PM UTC, comment #4: 

(Made the mistak eof just replyinf to the notification mail first)
Ha, ha, that's a good one😃 I of course know that passage from the manual - but I am bright enough to be willing to admit that I did not get it - for good reason. The point is that the reference to "line" is misleading: It should be clarified that a a complete command is meant - which could be simple (only then generally being a "line"), a pipeline, a list or a compound command (which I understand to include beyond "if"-blocks also function-definitions).

Martin Anantharaman <manantharaman>
Thu 15 Nov 2018 04:51:20 PM UTC, comment #3: 

Like this?

The  rules  concerning  the  definition and use of aliases are somewhat
       confusing.  Bash always reads at  least  one  complete  line  of  input
       before  executing  any  of  the  commands  on  that  line.  Aliases are
       expanded when a command is read, not when it is  executed.   Therefore,
       an  alias definition appearing on the same line as another command does
       not take effect until the next line of input  is  read.   The  commands
       following the alias definition on that line are not affected by the new
       alias.  This behavior is also an issue  when  functions  are  executed.
       Aliases  are  expanded when a function definition is read, not when the
       function is executed, because a function definition is  itself  a  com-
       mand.   As  a consequence, aliases defined in a function are not avail-
       able until after that function is executed.  To  be  safe,  always  put
       alias  definitions on a separate line, and do not use alias in compound
       commands.

Chet Ramey <chet>
Group administrator
Thu 15 Nov 2018 04:47:39 PM UTC, comment #2: 

Thanks for the explanation, I was assuming that the alias is "known" (and can be used) once it is parsed - ahead of code like functions using it - whereas I now understand that the alias needs to be executed before code using them is parsed. I had already segregated alias definitions to their own files (kind of like C-headers with definitions) and had meanwhile also sucessfully changed the logic of sourcing - I source conditionally but in a command list (like "[ "$lib" ] || source lib.sh") rather than in an if-block.

Maybe worth a comment in the manual somewhere, e.g. on compound commands or syntax in general under parsing vs. execution ...

Regards, Martin

Martin Anantharaman <manantharaman>
Thu 15 Nov 2018 04:10:37 PM UTC, comment #1: 

Aliases are expanded when a command is read and parsed, not when it is executed. A compound command like `if' or `while' is parsed completely before any of its commands are executed.

Once you put those two things together, the behavior is clear. The if command is read, but there are no aliases defined while it is being parsed -- the alias commands haven't been executed yet.

You need to make sure the aliases are defined in the current environment before sourcing the file. You can do this by sourcing the file with alias definitions before sourcing any files that use them.

Chet Ramey <chet>
Group administrator
Thu 15 Nov 2018 09:18:49 AM UTC, original submission:  

In trying to use a popular C-idiom in a library of shell-script(lets) I conditionalized code on the file not already being sourced - and then found that function-definitions no longer recognized valid alias-definitions (coming from other files, but that is probably immaterial), despite doing "shopt -s expand_aliases" - in fact the alias no longer works there at all.

Consider an example using the attachments: A "library" test-source-alias.sh sources test-source-alias-aliases.sh (which defines an alias test_alias) and then defines a function test_function. This fails when the function-definition (or even a call of test_alias) is in an if-block - but works outside. Running the example follows ...
[martin@MartinsDell ~]$ set -x
++ printf '\033]0;%s@%s:%s\007' martin MartinsDell '~'
[martin@MartinsDell ~]$ LC_ALL=C
+ LC_ALL=C
++ printf '\033]0;%s@%s:%s\007' martin MartinsDell '~'
[martin@MartinsDell ~]$ source test-source-alias.sh
+ source test-source-alias.sh
++ shopt -s expand_aliases
++ '[' '!' '' ']'
++ test_source_alias=true
++ source test-source-alias-aliases.sh
+++ '[' '!' '' ']'
+++ test_source_alias_aliases=true
+++ alias 'test_alias=echo test_alias called'
++ alias
alias e='emacsclient -c'
alias ll='ls -lF --show-control-chars'
alias ls='ls -F --color=auto --show-control-chars'
alias nosleep='systemd-inhibit'
alias test_alias='echo test_alias called'
++ shopt
autocd          off
cdable_vars     off
cdspell         off
checkhash       off
checkjobs       off
checkwinsize    on
cmdhist         on
compat31        off
compat32        off
compat40        off
compat41        off
compat42        off
compat43        off
complete_fullquote      on
direxpand       off
dirspell        off
dotglob         off
execfail        off
expand_aliases  on
extdebug        off
extglob         off
extquote        on
failglob        off
force_fignore   on
globasciiranges off
globstar        off
gnu_errfmt      off
histappend      off
histreedit      off
histverify      off
hostcomplete    on
huponexit       off
inherit_errexit off
interactive_comments    on
lastpipe        off
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        off
++ test_alias
bash: test_alias: command not found
++ test_function
++ test_alias
bash: test_alias: command not found
++ alias
alias e='emacsclient -c'
alias ll='ls -lF --show-control-chars'
alias ls='ls -F --color=auto --show-control-chars'
alias nosleep='systemd-inhibit'
alias test_alias='echo test_alias called'
++ shopt
autocd          off
cdable_vars     off
cdspell         off
checkhash       off
checkjobs       off
checkwinsize    on
cmdhist         on
compat31        off
compat32        off
compat40        off
compat41        off
compat42        off
compat43        off
complete_fullquote      on
direxpand       off
dirspell        off
dotglob         off
execfail        off
expand_aliases  on
extdebug        off
extglob         off
extquote        on
failglob        off
force_fignore   on
globasciiranges off
globstar        off
gnu_errfmt      off
histappend      off
histreedit      off
histverify      off
hostcomplete    on
huponexit       off
inherit_errexit off
interactive_comments    on
lastpipe        off
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        off
++ echo test_alias called
test_alias called
++ test_function
++ echo test_alias called
test_alias called
++ printf '\033]0;%s@%s:%s\007' martin MartinsDell '~'
[martin@MartinsDell ~]$

Am I missing something or is this intended behavioud?

Regards, Martin

Martin Anantharaman <manantharaman>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attached Files
file #45429:  test-source-alias.sh added by manantharaman (298B - application/x-shellscript)
file #45430:  test-source-alias-aliases.sh added by manantharaman (128B - application/x-shellscript)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by chet (Posted a comment)
  • -email is unavailable- added by manantharaman (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2018-11-15 chet StatusNone Invalid
    2018-11-15 manantharaman Attached File- Added test-source-alias.sh, #45429
        Attached File- Added test-source-alias-aliases.sh, #45430

    Back to the top

    Powered by Savane 3.14-f13d.
    Corresponding source code