Configuration Information [Automatically generated, do not change]: Machine: x86_64 OS: linux-gnu Compiler: gcc Compilation CFLAGS: -O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection -Wno-parentheses -Wno-format-security uname output: Linux yudev144 5.0.11-300.fc30.x86_64 #1 SMP Thu May 2 14:11:38 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux Machine Type: x86_64-redhat-linux-gnu
Bash Version: 5.0 Patch Level: 2 Release Status: release Description: This bug was found in bash 4.4.12 (GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)) It is still here in bash 5.0.2. I pubilshed it first in this page, https://unix.stackexchange.com/questions/406674/bash-why-is-alias-after-newline-ignored-when-run-remotely#407064 This is a bug of option '-c'. It can be reproduced with the command below, bash -c "shopt -s expand_aliases &>/dev/null; alias myalias='echo foo echo bar echo baz' myalias I expect it to output such three lines as follows, foo bar baz But only 'foo' will be output. To get the right/expected output, at least one more line has to be added after 'myalias', like below, bash -c "shopt -s expand_aliases &>/dev/null; alias myalias='echo foo echo bar echo baz' myalias :" After read the code, I found a solution to fix it without changing any code, that is to compile bash with 'ONESHOT' undefined. Whether define 'ONESHOT' or not leads to two completely different route in Bash code for '-c "command"'. If undefine 'ONESHOT', '-c "command"' will run the normal code route, which is the code route for almost all bash executions, such as interactive command and bash script. But if define 'ONESHOT', '-c "command"' will run another particular route which is specially designed for '-c' only, to improve its performance by avoiding fork. The bug is right in the particular route. -------- Some details about this bug The following piece of code is where the bug is. It is from function parse_and_execute() in file builtins/evalstring.c, which is the one enabled by 'ONESHOT'. while (*(bash_input.location.string)) { ... } This while loop will run by lines, handling one line in one loop. After read 'myalias', the last line in the problematic command (see above), the condition in while will become false. 'myalias' is expanded to three lines of echo, but only one echo is handled in this loop; the two other echos are intended to be handled in next loops, but... there is no more loops. If you add one more line after 'myalias', after read 'myalias', the condition in while will remain true, so the two other echos will get chance to run in next loops. The last line after 'myalias' will be handled after all echos expanded from 'myalias' are handled.