Here documents as multiple lines command within the bash
Clash Royale CLAN TAG#URR8PPP
up vote
1
down vote
favorite
I created a snippet to test the here document
$ cat test101.sh
ls
$ bash test101.sh
bmdt.md brmdh.md fild.md test test101.sh test2 test5 testfile
breakfast.md exec file.md test.sh test12 test3 test7
It come to Here document
$ $(cat << EOF
â ls
â EOF)
bmdt.md brmdh.md fild.md test test101.sh test2 test5 testfile
breakfast.md exec file.md test.sh test12 test3 test7
It works properly,
Unfortunately, it's not the case of structured command
$ $(cat << EOF
â for i in *
â do
â stat $i
â done
â EOF)
-bash: for: command not found
I tried alternatively
$ bash $(cat << EOF
â for i in *
â do
â stat $i
â done
â EOF)
bash: for: No such file or directory
What's the problem not allow the for command working?
bash
New contributor
add a comment |Â
up vote
1
down vote
favorite
I created a snippet to test the here document
$ cat test101.sh
ls
$ bash test101.sh
bmdt.md brmdh.md fild.md test test101.sh test2 test5 testfile
breakfast.md exec file.md test.sh test12 test3 test7
It come to Here document
$ $(cat << EOF
â ls
â EOF)
bmdt.md brmdh.md fild.md test test101.sh test2 test5 testfile
breakfast.md exec file.md test.sh test12 test3 test7
It works properly,
Unfortunately, it's not the case of structured command
$ $(cat << EOF
â for i in *
â do
â stat $i
â done
â EOF)
-bash: for: command not found
I tried alternatively
$ bash $(cat << EOF
â for i in *
â do
â stat $i
â done
â EOF)
bash: for: No such file or directory
What's the problem not allow the for command working?
bash
New contributor
What are you trying to accomplish by using loop inside heredoc?
â user1700494
2 hours ago
learning to get a better understanding about how heredoc work. @user1700494
â avirate
2 hours ago
You'd need to escape the special characters, e.g.*
->*
,$i
->$i
â steve
2 hours ago
1
@steve The*
does not need special treatment as the shell won't do filename globbing on the contents of the document, only expansions.
â Kusalananda
2 hours ago
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I created a snippet to test the here document
$ cat test101.sh
ls
$ bash test101.sh
bmdt.md brmdh.md fild.md test test101.sh test2 test5 testfile
breakfast.md exec file.md test.sh test12 test3 test7
It come to Here document
$ $(cat << EOF
â ls
â EOF)
bmdt.md brmdh.md fild.md test test101.sh test2 test5 testfile
breakfast.md exec file.md test.sh test12 test3 test7
It works properly,
Unfortunately, it's not the case of structured command
$ $(cat << EOF
â for i in *
â do
â stat $i
â done
â EOF)
-bash: for: command not found
I tried alternatively
$ bash $(cat << EOF
â for i in *
â do
â stat $i
â done
â EOF)
bash: for: No such file or directory
What's the problem not allow the for command working?
bash
New contributor
I created a snippet to test the here document
$ cat test101.sh
ls
$ bash test101.sh
bmdt.md brmdh.md fild.md test test101.sh test2 test5 testfile
breakfast.md exec file.md test.sh test12 test3 test7
It come to Here document
$ $(cat << EOF
â ls
â EOF)
bmdt.md brmdh.md fild.md test test101.sh test2 test5 testfile
breakfast.md exec file.md test.sh test12 test3 test7
It works properly,
Unfortunately, it's not the case of structured command
$ $(cat << EOF
â for i in *
â do
â stat $i
â done
â EOF)
-bash: for: command not found
I tried alternatively
$ bash $(cat << EOF
â for i in *
â do
â stat $i
â done
â EOF)
bash: for: No such file or directory
What's the problem not allow the for command working?
bash
bash
New contributor
New contributor
New contributor
asked 3 hours ago
avirate
41829
41829
New contributor
New contributor
What are you trying to accomplish by using loop inside heredoc?
â user1700494
2 hours ago
learning to get a better understanding about how heredoc work. @user1700494
â avirate
2 hours ago
You'd need to escape the special characters, e.g.*
->*
,$i
->$i
â steve
2 hours ago
1
@steve The*
does not need special treatment as the shell won't do filename globbing on the contents of the document, only expansions.
â Kusalananda
2 hours ago
add a comment |Â
What are you trying to accomplish by using loop inside heredoc?
â user1700494
2 hours ago
learning to get a better understanding about how heredoc work. @user1700494
â avirate
2 hours ago
You'd need to escape the special characters, e.g.*
->*
,$i
->$i
â steve
2 hours ago
1
@steve The*
does not need special treatment as the shell won't do filename globbing on the contents of the document, only expansions.
â Kusalananda
2 hours ago
What are you trying to accomplish by using loop inside heredoc?
â user1700494
2 hours ago
What are you trying to accomplish by using loop inside heredoc?
â user1700494
2 hours ago
learning to get a better understanding about how heredoc work. @user1700494
â avirate
2 hours ago
learning to get a better understanding about how heredoc work. @user1700494
â avirate
2 hours ago
You'd need to escape the special characters, e.g.
*
-> *
, $i
-> $i
â steve
2 hours ago
You'd need to escape the special characters, e.g.
*
-> *
, $i
-> $i
â steve
2 hours ago
1
1
@steve The
*
does not need special treatment as the shell won't do filename globbing on the contents of the document, only expansions.â Kusalananda
2 hours ago
@steve The
*
does not need special treatment as the shell won't do filename globbing on the contents of the document, only expansions.â Kusalananda
2 hours ago
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
3
down vote
accepted
A here-document is a form of redirection. In your commands, you redirect into the cat
command, and then try to use the output as a command in a command substitution.
$i
will be expanded when the contents of the here-document is formed. This happens long before the loop in the document actually runs. If thei
variable is unset, it will expand to an empty string. You may choose to quote the here-document (by quoting the firstEOF
as'EOF'
orEOF
) so that no expansions are done in it, or to explicitly escape the$
as$
to protect it from expansion.- The contents of the here-document will be interpreted as a single string with new-line delimited lines. It will not undergo the usual token recognition and other steps involved in the parsing of ordinary commands, but will be split up into individual words since the command substitution is unquoted. In particular,
for
will not be recognised as a shell keyword. This is why your first failing example fails. To re-evaluate the string, you would have toeval
it, which would re-evaluate the string as the shell would have done had it been given on the command line. The last example would expand to
bash
followed by a number of words. The first word isfor
, sobash
would expect to run a shell script calledfor
in the current directory, but fails in doing so.In all examples,
bash
should also have complained that the here-document was not properly terminated (since the last line isEOF)
with a trailing right parenthesis, notEOF
), saying something likebash: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
unless you are using an older
bash
release, like the default one on macOS.
Instead, this would be a better choice of actions as it avoids converting code into a string that needs to be re-interpreted and instead gives the document as a in-line shell script directly to a shell interpreter to execute.
bash <<'END_SCRIPT'
for i in *; do
printf 'Filename: "%s"n' "$i"
done
END_SCRIPT
The first of your examples work because it's a simple command.
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
accepted
A here-document is a form of redirection. In your commands, you redirect into the cat
command, and then try to use the output as a command in a command substitution.
$i
will be expanded when the contents of the here-document is formed. This happens long before the loop in the document actually runs. If thei
variable is unset, it will expand to an empty string. You may choose to quote the here-document (by quoting the firstEOF
as'EOF'
orEOF
) so that no expansions are done in it, or to explicitly escape the$
as$
to protect it from expansion.- The contents of the here-document will be interpreted as a single string with new-line delimited lines. It will not undergo the usual token recognition and other steps involved in the parsing of ordinary commands, but will be split up into individual words since the command substitution is unquoted. In particular,
for
will not be recognised as a shell keyword. This is why your first failing example fails. To re-evaluate the string, you would have toeval
it, which would re-evaluate the string as the shell would have done had it been given on the command line. The last example would expand to
bash
followed by a number of words. The first word isfor
, sobash
would expect to run a shell script calledfor
in the current directory, but fails in doing so.In all examples,
bash
should also have complained that the here-document was not properly terminated (since the last line isEOF)
with a trailing right parenthesis, notEOF
), saying something likebash: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
unless you are using an older
bash
release, like the default one on macOS.
Instead, this would be a better choice of actions as it avoids converting code into a string that needs to be re-interpreted and instead gives the document as a in-line shell script directly to a shell interpreter to execute.
bash <<'END_SCRIPT'
for i in *; do
printf 'Filename: "%s"n' "$i"
done
END_SCRIPT
The first of your examples work because it's a simple command.
add a comment |Â
up vote
3
down vote
accepted
A here-document is a form of redirection. In your commands, you redirect into the cat
command, and then try to use the output as a command in a command substitution.
$i
will be expanded when the contents of the here-document is formed. This happens long before the loop in the document actually runs. If thei
variable is unset, it will expand to an empty string. You may choose to quote the here-document (by quoting the firstEOF
as'EOF'
orEOF
) so that no expansions are done in it, or to explicitly escape the$
as$
to protect it from expansion.- The contents of the here-document will be interpreted as a single string with new-line delimited lines. It will not undergo the usual token recognition and other steps involved in the parsing of ordinary commands, but will be split up into individual words since the command substitution is unquoted. In particular,
for
will not be recognised as a shell keyword. This is why your first failing example fails. To re-evaluate the string, you would have toeval
it, which would re-evaluate the string as the shell would have done had it been given on the command line. The last example would expand to
bash
followed by a number of words. The first word isfor
, sobash
would expect to run a shell script calledfor
in the current directory, but fails in doing so.In all examples,
bash
should also have complained that the here-document was not properly terminated (since the last line isEOF)
with a trailing right parenthesis, notEOF
), saying something likebash: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
unless you are using an older
bash
release, like the default one on macOS.
Instead, this would be a better choice of actions as it avoids converting code into a string that needs to be re-interpreted and instead gives the document as a in-line shell script directly to a shell interpreter to execute.
bash <<'END_SCRIPT'
for i in *; do
printf 'Filename: "%s"n' "$i"
done
END_SCRIPT
The first of your examples work because it's a simple command.
add a comment |Â
up vote
3
down vote
accepted
up vote
3
down vote
accepted
A here-document is a form of redirection. In your commands, you redirect into the cat
command, and then try to use the output as a command in a command substitution.
$i
will be expanded when the contents of the here-document is formed. This happens long before the loop in the document actually runs. If thei
variable is unset, it will expand to an empty string. You may choose to quote the here-document (by quoting the firstEOF
as'EOF'
orEOF
) so that no expansions are done in it, or to explicitly escape the$
as$
to protect it from expansion.- The contents of the here-document will be interpreted as a single string with new-line delimited lines. It will not undergo the usual token recognition and other steps involved in the parsing of ordinary commands, but will be split up into individual words since the command substitution is unquoted. In particular,
for
will not be recognised as a shell keyword. This is why your first failing example fails. To re-evaluate the string, you would have toeval
it, which would re-evaluate the string as the shell would have done had it been given on the command line. The last example would expand to
bash
followed by a number of words. The first word isfor
, sobash
would expect to run a shell script calledfor
in the current directory, but fails in doing so.In all examples,
bash
should also have complained that the here-document was not properly terminated (since the last line isEOF)
with a trailing right parenthesis, notEOF
), saying something likebash: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
unless you are using an older
bash
release, like the default one on macOS.
Instead, this would be a better choice of actions as it avoids converting code into a string that needs to be re-interpreted and instead gives the document as a in-line shell script directly to a shell interpreter to execute.
bash <<'END_SCRIPT'
for i in *; do
printf 'Filename: "%s"n' "$i"
done
END_SCRIPT
The first of your examples work because it's a simple command.
A here-document is a form of redirection. In your commands, you redirect into the cat
command, and then try to use the output as a command in a command substitution.
$i
will be expanded when the contents of the here-document is formed. This happens long before the loop in the document actually runs. If thei
variable is unset, it will expand to an empty string. You may choose to quote the here-document (by quoting the firstEOF
as'EOF'
orEOF
) so that no expansions are done in it, or to explicitly escape the$
as$
to protect it from expansion.- The contents of the here-document will be interpreted as a single string with new-line delimited lines. It will not undergo the usual token recognition and other steps involved in the parsing of ordinary commands, but will be split up into individual words since the command substitution is unquoted. In particular,
for
will not be recognised as a shell keyword. This is why your first failing example fails. To re-evaluate the string, you would have toeval
it, which would re-evaluate the string as the shell would have done had it been given on the command line. The last example would expand to
bash
followed by a number of words. The first word isfor
, sobash
would expect to run a shell script calledfor
in the current directory, but fails in doing so.In all examples,
bash
should also have complained that the here-document was not properly terminated (since the last line isEOF)
with a trailing right parenthesis, notEOF
), saying something likebash: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
unless you are using an older
bash
release, like the default one on macOS.
Instead, this would be a better choice of actions as it avoids converting code into a string that needs to be re-interpreted and instead gives the document as a in-line shell script directly to a shell interpreter to execute.
bash <<'END_SCRIPT'
for i in *; do
printf 'Filename: "%s"n' "$i"
done
END_SCRIPT
The first of your examples work because it's a simple command.
edited 1 hour ago
answered 2 hours ago
Kusalananda
112k15216343
112k15216343
add a comment |Â
add a comment |Â
avirate is a new contributor. Be nice, and check out our Code of Conduct.
avirate is a new contributor. Be nice, and check out our Code of Conduct.
avirate is a new contributor. Be nice, and check out our Code of Conduct.
avirate is a new contributor. Be nice, and check out our Code of Conduct.
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f478261%2fhere-documents-as-multiple-lines-command-within-the-bash%23new-answer', 'question_page');
);
Post as a guest
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
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
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
What are you trying to accomplish by using loop inside heredoc?
â user1700494
2 hours ago
learning to get a better understanding about how heredoc work. @user1700494
â avirate
2 hours ago
You'd need to escape the special characters, e.g.
*
->*
,$i
->$i
â steve
2 hours ago
1
@steve The
*
does not need special treatment as the shell won't do filename globbing on the contents of the document, only expansions.â Kusalananda
2 hours ago