bash aliases do not expand even with shopt expand_aliases
I want to run an alias inside a bash -c
construct.
The bash
manual says:
Aliases are not expanded when the shell is not interactive, unless the
expand_aliases
shell option is set usingshopt
In this example, why is the alias hi
not found when setting expand_aliases
explicitly?
% bash -O expand_aliases -c "alias hi='echo hello'; alias; shopt expand_aliases; hi"
alias hi='echo hello'
expand_aliases on
bash: hi: command not found
I'm running GNU bash, version 5.0.0(1)-release (x86_64-pc-linux-gnu)
.
Context: I want to be able to run an alias at idle priority, eg a script containing:
#!/bin/bash
exec chrt -i 0 nice -n 19 ionice -c 3 bash -c ". ~/.config/bash/aliases; shopt -s expand_aliases; $(shell-quote "$@")"
I want to avoid using bash -i
as I don't want my .bashrc
to be read.
bash alias
add a comment |
I want to run an alias inside a bash -c
construct.
The bash
manual says:
Aliases are not expanded when the shell is not interactive, unless the
expand_aliases
shell option is set usingshopt
In this example, why is the alias hi
not found when setting expand_aliases
explicitly?
% bash -O expand_aliases -c "alias hi='echo hello'; alias; shopt expand_aliases; hi"
alias hi='echo hello'
expand_aliases on
bash: hi: command not found
I'm running GNU bash, version 5.0.0(1)-release (x86_64-pc-linux-gnu)
.
Context: I want to be able to run an alias at idle priority, eg a script containing:
#!/bin/bash
exec chrt -i 0 nice -n 19 ionice -c 3 bash -c ". ~/.config/bash/aliases; shopt -s expand_aliases; $(shell-quote "$@")"
I want to avoid using bash -i
as I don't want my .bashrc
to be read.
bash alias
2
The paragraph right after the quoted statement from the Bash manual seems to cover this: '...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....'
– Haxiel
15 hours ago
As in most cases, you should consider using a shell function instead of an alias here.bash -c "hi () { echo hello; }; hi"
outputshello
.
– chepner
8 hours ago
add a comment |
I want to run an alias inside a bash -c
construct.
The bash
manual says:
Aliases are not expanded when the shell is not interactive, unless the
expand_aliases
shell option is set usingshopt
In this example, why is the alias hi
not found when setting expand_aliases
explicitly?
% bash -O expand_aliases -c "alias hi='echo hello'; alias; shopt expand_aliases; hi"
alias hi='echo hello'
expand_aliases on
bash: hi: command not found
I'm running GNU bash, version 5.0.0(1)-release (x86_64-pc-linux-gnu)
.
Context: I want to be able to run an alias at idle priority, eg a script containing:
#!/bin/bash
exec chrt -i 0 nice -n 19 ionice -c 3 bash -c ". ~/.config/bash/aliases; shopt -s expand_aliases; $(shell-quote "$@")"
I want to avoid using bash -i
as I don't want my .bashrc
to be read.
bash alias
I want to run an alias inside a bash -c
construct.
The bash
manual says:
Aliases are not expanded when the shell is not interactive, unless the
expand_aliases
shell option is set usingshopt
In this example, why is the alias hi
not found when setting expand_aliases
explicitly?
% bash -O expand_aliases -c "alias hi='echo hello'; alias; shopt expand_aliases; hi"
alias hi='echo hello'
expand_aliases on
bash: hi: command not found
I'm running GNU bash, version 5.0.0(1)-release (x86_64-pc-linux-gnu)
.
Context: I want to be able to run an alias at idle priority, eg a script containing:
#!/bin/bash
exec chrt -i 0 nice -n 19 ionice -c 3 bash -c ". ~/.config/bash/aliases; shopt -s expand_aliases; $(shell-quote "$@")"
I want to avoid using bash -i
as I don't want my .bashrc
to be read.
bash alias
bash alias
edited 15 hours ago
Tom Hale
asked 15 hours ago
Tom HaleTom Hale
7,13533797
7,13533797
2
The paragraph right after the quoted statement from the Bash manual seems to cover this: '...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....'
– Haxiel
15 hours ago
As in most cases, you should consider using a shell function instead of an alias here.bash -c "hi () { echo hello; }; hi"
outputshello
.
– chepner
8 hours ago
add a comment |
2
The paragraph right after the quoted statement from the Bash manual seems to cover this: '...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....'
– Haxiel
15 hours ago
As in most cases, you should consider using a shell function instead of an alias here.bash -c "hi () { echo hello; }; hi"
outputshello
.
– chepner
8 hours ago
2
2
The paragraph right after the quoted statement from the Bash manual seems to cover this: '...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....'
– Haxiel
15 hours ago
The paragraph right after the quoted statement from the Bash manual seems to cover this: '...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....'
– Haxiel
15 hours ago
As in most cases, you should consider using a shell function instead of an alias here.
bash -c "hi () { echo hello; }; hi"
outputs hello
.– chepner
8 hours ago
As in most cases, you should consider using a shell function instead of an alias here.
bash -c "hi () { echo hello; }; hi"
outputs hello
.– chepner
8 hours ago
add a comment |
2 Answers
2
active
oldest
votes
It doesn't seem work if you set the alias on the same line as it's used. Probably something to do with how aliases are expanded really early in the command line processing, before the actual parsing stage. On an interactive shell:
$ alias foo
bash: alias: foo: not found
$ alias foo='echo foo'; foo # 2
bash: foo: command not found
$ alias foo='echo bar'; foo # 3
foo
$ foo
bar
Note how the alias used is one line late: on the second command it doesn't find the alias just set, and on the third command it uses the one that was previously set.
So, it works if we put a newline within the -c
string:
$ bash -c $'shopt -s expand_aliases; alias foo="echo foo";n foo'
foo
(You could also use bash -O expand_aliases -c ...
instead of using shopt
within the script, not that it helps with the newline.)
Alternatively, you could use a shell function instead of an alias, they're much better in other ways, too:
$ bash -c 'foo() { echo foo; }; foo'
foo
add a comment |
Turning my comment into an answer, as suggested by ilkkachu.
The Bash manual (linked to in the question) does provide an explanation of how the aliases are handled when there is an alias definition and a command on the same line.
Quote (slightly formatted for clarity):
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.
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 command. As a
consequence, aliases defined in a function are not available 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.
ilkkachu's answer provides multiple possible solutions to this problem.
FWIW, I saw your last comment but didn't have time to answer. It's not a bad thing for answers to complement others, and knowing it's actually documented that way is useful. So thanks for writing this up, now I can upvote it. :)
– ilkkachu
11 hours ago
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f502257%2fbash-aliases-do-not-expand-even-with-shopt-expand-aliases%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
It doesn't seem work if you set the alias on the same line as it's used. Probably something to do with how aliases are expanded really early in the command line processing, before the actual parsing stage. On an interactive shell:
$ alias foo
bash: alias: foo: not found
$ alias foo='echo foo'; foo # 2
bash: foo: command not found
$ alias foo='echo bar'; foo # 3
foo
$ foo
bar
Note how the alias used is one line late: on the second command it doesn't find the alias just set, and on the third command it uses the one that was previously set.
So, it works if we put a newline within the -c
string:
$ bash -c $'shopt -s expand_aliases; alias foo="echo foo";n foo'
foo
(You could also use bash -O expand_aliases -c ...
instead of using shopt
within the script, not that it helps with the newline.)
Alternatively, you could use a shell function instead of an alias, they're much better in other ways, too:
$ bash -c 'foo() { echo foo; }; foo'
foo
add a comment |
It doesn't seem work if you set the alias on the same line as it's used. Probably something to do with how aliases are expanded really early in the command line processing, before the actual parsing stage. On an interactive shell:
$ alias foo
bash: alias: foo: not found
$ alias foo='echo foo'; foo # 2
bash: foo: command not found
$ alias foo='echo bar'; foo # 3
foo
$ foo
bar
Note how the alias used is one line late: on the second command it doesn't find the alias just set, and on the third command it uses the one that was previously set.
So, it works if we put a newline within the -c
string:
$ bash -c $'shopt -s expand_aliases; alias foo="echo foo";n foo'
foo
(You could also use bash -O expand_aliases -c ...
instead of using shopt
within the script, not that it helps with the newline.)
Alternatively, you could use a shell function instead of an alias, they're much better in other ways, too:
$ bash -c 'foo() { echo foo; }; foo'
foo
add a comment |
It doesn't seem work if you set the alias on the same line as it's used. Probably something to do with how aliases are expanded really early in the command line processing, before the actual parsing stage. On an interactive shell:
$ alias foo
bash: alias: foo: not found
$ alias foo='echo foo'; foo # 2
bash: foo: command not found
$ alias foo='echo bar'; foo # 3
foo
$ foo
bar
Note how the alias used is one line late: on the second command it doesn't find the alias just set, and on the third command it uses the one that was previously set.
So, it works if we put a newline within the -c
string:
$ bash -c $'shopt -s expand_aliases; alias foo="echo foo";n foo'
foo
(You could also use bash -O expand_aliases -c ...
instead of using shopt
within the script, not that it helps with the newline.)
Alternatively, you could use a shell function instead of an alias, they're much better in other ways, too:
$ bash -c 'foo() { echo foo; }; foo'
foo
It doesn't seem work if you set the alias on the same line as it's used. Probably something to do with how aliases are expanded really early in the command line processing, before the actual parsing stage. On an interactive shell:
$ alias foo
bash: alias: foo: not found
$ alias foo='echo foo'; foo # 2
bash: foo: command not found
$ alias foo='echo bar'; foo # 3
foo
$ foo
bar
Note how the alias used is one line late: on the second command it doesn't find the alias just set, and on the third command it uses the one that was previously set.
So, it works if we put a newline within the -c
string:
$ bash -c $'shopt -s expand_aliases; alias foo="echo foo";n foo'
foo
(You could also use bash -O expand_aliases -c ...
instead of using shopt
within the script, not that it helps with the newline.)
Alternatively, you could use a shell function instead of an alias, they're much better in other ways, too:
$ bash -c 'foo() { echo foo; }; foo'
foo
answered 15 hours ago
ilkkachuilkkachu
59.7k895169
59.7k895169
add a comment |
add a comment |
Turning my comment into an answer, as suggested by ilkkachu.
The Bash manual (linked to in the question) does provide an explanation of how the aliases are handled when there is an alias definition and a command on the same line.
Quote (slightly formatted for clarity):
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.
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 command. As a
consequence, aliases defined in a function are not available 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.
ilkkachu's answer provides multiple possible solutions to this problem.
FWIW, I saw your last comment but didn't have time to answer. It's not a bad thing for answers to complement others, and knowing it's actually documented that way is useful. So thanks for writing this up, now I can upvote it. :)
– ilkkachu
11 hours ago
add a comment |
Turning my comment into an answer, as suggested by ilkkachu.
The Bash manual (linked to in the question) does provide an explanation of how the aliases are handled when there is an alias definition and a command on the same line.
Quote (slightly formatted for clarity):
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.
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 command. As a
consequence, aliases defined in a function are not available 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.
ilkkachu's answer provides multiple possible solutions to this problem.
FWIW, I saw your last comment but didn't have time to answer. It's not a bad thing for answers to complement others, and knowing it's actually documented that way is useful. So thanks for writing this up, now I can upvote it. :)
– ilkkachu
11 hours ago
add a comment |
Turning my comment into an answer, as suggested by ilkkachu.
The Bash manual (linked to in the question) does provide an explanation of how the aliases are handled when there is an alias definition and a command on the same line.
Quote (slightly formatted for clarity):
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.
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 command. As a
consequence, aliases defined in a function are not available 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.
ilkkachu's answer provides multiple possible solutions to this problem.
Turning my comment into an answer, as suggested by ilkkachu.
The Bash manual (linked to in the question) does provide an explanation of how the aliases are handled when there is an alias definition and a command on the same line.
Quote (slightly formatted for clarity):
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.
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 command. As a
consequence, aliases defined in a function are not available 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.
ilkkachu's answer provides multiple possible solutions to this problem.
answered 14 hours ago
HaxielHaxiel
2,8951917
2,8951917
FWIW, I saw your last comment but didn't have time to answer. It's not a bad thing for answers to complement others, and knowing it's actually documented that way is useful. So thanks for writing this up, now I can upvote it. :)
– ilkkachu
11 hours ago
add a comment |
FWIW, I saw your last comment but didn't have time to answer. It's not a bad thing for answers to complement others, and knowing it's actually documented that way is useful. So thanks for writing this up, now I can upvote it. :)
– ilkkachu
11 hours ago
FWIW, I saw your last comment but didn't have time to answer. It's not a bad thing for answers to complement others, and knowing it's actually documented that way is useful. So thanks for writing this up, now I can upvote it. :)
– ilkkachu
11 hours ago
FWIW, I saw your last comment but didn't have time to answer. It's not a bad thing for answers to complement others, and knowing it's actually documented that way is useful. So thanks for writing this up, now I can upvote it. :)
– ilkkachu
11 hours ago
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f502257%2fbash-aliases-do-not-expand-even-with-shopt-expand-aliases%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
The paragraph right after the quoted statement from the Bash manual seems to cover this: '...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....'
– Haxiel
15 hours ago
As in most cases, you should consider using a shell function instead of an alias here.
bash -c "hi () { echo hello; }; hi"
outputshello
.– chepner
8 hours ago