Unix & Linux Stack Exchange
Q&A for users of Linux, FreeBSD and other Unix-like operating systems
Latest Questions
0
votes
0
answers
43
views
bash variable substitution inside heredoc delimiter: how does it work?
For a school project, I am tasked with making my own (simplified) shell, with bash being the reference point. This includes replicating heredoc behavior which was fun until I stumbled upon variable substitution INSIDE of the delimiter, as such: ```export TESTVAR=hello``` followed by cat hello > $TES...
For a school project, I am tasked with making my own (simplified) shell, with bash being the reference point. This includes replicating heredoc behavior which was fun until I stumbled upon variable substitution INSIDE of the delimiter, as such:
TESTVAR=hello
followed by
cat hello
> $TESTVAR
hello
As demonstrated here, typing the value of the variable manually does not end the heredoc, whereas typing $TESTVAR
does. Does this mean that variables are not substituted if they're inside of the delimiter?
Disabling variable substitution results in the same thing:
cat hello
> $TESTVAR
hello
And getting wild with the quotes also results in the same thing:
cat hello
> TVAR
> $TESTVAR
hello
TVAR
All evidence seems to point towards $TESTVAR
does not get substituted **because** it is part of a heredoc delimiter, but I can't find a definitive answer to this! Does anyone know?
Mika
(101 rep)
May 9, 2025, 01:58 PM
• Last activity: May 9, 2025, 02:17 PM
2
votes
1
answers
220
views
Using Here-Document as password Input for ssh
First, I do know this is a security risk. I do know about ssh keys and sshpass. This belongs to a **fun** project. I wondered if a bash Here-Document could be used as a password input for ssh. I unseccessfully tried something like ssh localhost <<! mytestpasswd /bin/bash ! Sadly the bash terminates....
First, I do know this is a security risk. I do know about ssh keys and sshpass. This belongs to a **fun** project.
I wondered if a bash Here-Document could be used as a password input for ssh.
I unseccessfully tried something like
ssh localhost <
Simon Huenecke
(29 rep)
Apr 22, 2025, 10:25 AM
• Last activity: Apr 22, 2025, 12:01 PM
6
votes
2
answers
823
views
Is it possible to define a bash heredoc with a multi-word delimiter that expands variables?
Consider the following script: ``` #!/bin/bash foo=Hello bar=Word cat <<EOF No quotes single word delimiter expands $foo $bar EOF cat <<'EOF' Single-quoted single word delimiter does not expand. $foo $bar EOF cat <<"EOF" Double-quoted single word delimiter does not expand. $foo $bar EOF cat <<EOF\ S...
Consider the following script:
#!/bin/bash
foo=Hello
bar=Word
cat <
In the last case, I am using a multi-word, unquoted delimiter but the output is the following:
Unquoted multi-word word delimiter does not expand.
Can we get it to expand?
$foo
$bar
Is there a way to get bash to expand variables when using a multi-word heredoc delimiter?
merlin2011
(4139 rep)
Apr 2, 2025, 05:51 AM
• Last activity: Apr 3, 2025, 06:48 AM
8
votes
1
answers
892
views
Why does bash with "here documents" redirection start as interactive?
I found the following in `man bash` as a definition of interactive shell: > An interactive shell is one started without non-option arguments > (unless -s is specified) and without the -c option whose standard > input and error are both connected to terminals (as determined by > isatty(3)), or one st...
I found the following in
man bash
as a definition of interactive shell:
> An interactive shell is one started without non-option arguments
> (unless -s is specified) and without the -c option whose standard
> input and error are both connected to terminals (as determined by
> isatty(3)), or one started with the -i option. PS1 is set and $-
> includes i if bash is interactive, allowing a shell script or a
> startup file to test this state.
So, interactive shell is the one that:
1. doesn't have non-option arguments (unless -s
is specified), doesn't have -c
option and whose standard input and error are both connected to terminal; or
2. has -i
option
I wrote the following example:
```
bash This type of redirection instructs the shell to read input from the
> current source until a line containing only delimiter (with no
> trailing blanks) is seen. **All of the lines read up to that point
> are then used as the standard input** (or file descriptor n if n is
> specified) for a command.
It says that standard input is all lines read up to the delimiter (I assume that they are then passed to the command by redirecting the command's standard input to a pipe or something like that). Therefore, standard input is not (connected to) a terminal.
Why is this happening? Why is bash interactive in this case?
Yakog
(517 rep)
Feb 25, 2025, 09:12 PM
• Last activity: Feb 25, 2025, 10:34 PM
0
votes
1
answers
63
views
How can I use a here-document on the left-hand side of a pipeline?
Show lines passed by here-document in the stdout: cat <<EOF foo bar baz EOF foo bar baz I want to match some string with grep via pipe: cat <<EOF foo bar baz EOF |grep 'ba' Why can't pass the stdout through pipe for grep command?
Show lines passed by here-document in the stdout:
cat <
showkey
(499 rep)
Feb 14, 2025, 04:06 AM
• Last activity: Feb 14, 2025, 07:50 AM
27
votes
4
answers
9577
views
Is it possible to use multiple here-docs in bash?
Can one use multiple here-docs to provide input to a command in bash? $ cat foo > EOF1 > bar > EOF2 bar Obviously, in both cases, the second here-doc is used as stdin, and replaces the first reference. Is the solution to use `echo`s instead? $ cat <(echo -n foo) <(echo bar) foobar Also, for some rea...
Can one use multiple here-docs to provide input to a command in bash?
$ cat foo
> EOF1
> bar
> EOF2
bar
Obviously, in both cases, the second here-doc is used as stdin, and replaces the first reference. Is the solution to use
echo
s instead?
$ cat <(echo -n foo) <(echo bar)
foobar
Also, for some reason, using a combination didn't work for me. Why would that be?
$ cat <<
Sparhawk
(20499 rep)
Aug 3, 2014, 11:10 AM
• Last activity: Oct 26, 2024, 07:16 AM
5
votes
3
answers
1138
views
How can I assign a heredoc to a variable in a way that's portable across Unix and Mac?
This code works fine on Linux but not Mac OS: ``` #!/usr/bin/env bash foo=$(cat <<EOF "\[^"\]+" EOF ) printf "%s" "$foo" ``` It fails on Mac with ``` ./test.sh: line 6: unexpected EOF while looking for matching `"' ./test.sh: line 7: syntax error: unexpected end of file ``` If I do `cat <<EOF` inste...
This code works fine on Linux but not Mac OS:
#!/usr/bin/env bash
foo=$(cat <
It fails on Mac with
./test.sh: line 6: unexpected EOF while looking for matching `"'
./test.sh: line 7: syntax error: unexpected end of file
If I do cat < instead of foo=$(cat <, it works fine. Is there a portable way to get heredocs (or multiline strings) into variables without using a file as an intermediate?
**Edit**: I want to use a heredoc becuase I have a multiline string with "
and '
. My actual example looks like:
EXPECTED_ERROR=$(cat <
Jason Gross
(173 rep)
Sep 17, 2024, 02:55 AM
• Last activity: Oct 9, 2024, 05:41 PM
0
votes
2
answers
133
views
Cat file and heredoc to pipe
I do some automatic checks and want to send a mail if a file has changed. I want the mail body to contain the new version of the file, some static text and the old version of the file, so what I do is cat mettab.txt metalerttext.txt mettab.old.txt | /usr/bin/mail -s Metalerts (...) where mettab.txt...
I do some automatic checks and want to send a mail if a file has changed. I want the mail body to contain the new version of the file, some static text and the old version of the file, so what I do is
cat mettab.txt metalerttext.txt mettab.old.txt | /usr/bin/mail -s Metalerts (...)
where mettab.txt is the new version, metalerttext.txt is a static file and mettab.old.txt is the old version.
but, rather than using metalerttext.txt, I feel it would be better to use a heredoc. But is it possible to do that in a single line as above, or is the only possibility to make a temporary file and do something like:
cp mettab.txt mailtemp.txt
cat > mailtemp.txt
cat mettab.old.txt >> mailtemp.txt
before mailing mailtemp.txt and deleting the file.
Or have I overlooked someting? (metalerttext.txt is just one line)
MortenSickel
(1433 rep)
May 31, 2024, 12:42 PM
• Last activity: May 31, 2024, 07:04 PM
11
votes
1
answers
1312
views
Bash 4: unexpected EOF while looking for matching `)'
This very simplified version of my script ``` #!/usr/bin/env bash example="$(bash -rs <<'BASH' -- 'This has been executed in restricted shell' echo "$1" BASH )" echo "$example" ``` is executed without problems on a system with bash version 5.1.4. However, on another system with bash version 4.0.44,...
This very simplified version of my script
#!/usr/bin/env bash
example="$(bash -rs <<'BASH' -- 'This has been executed in restricted shell'
echo "$1"
BASH
)"
echo "$example"
is executed without problems on a system with bash version 5.1.4. However, on another system with bash version 4.0.44, I get the error
line 2: unexpected EOF while looking for matching `)'
If I change the script to
#!/usr/bin/env bash
example="$(bash -rs <<'BASH'
echo 'This has been executed in restricted shell'
BASH
)"
echo "$example"
or
#!/usr/bin/env bash
bash -rs <<'BASH' -- 'This has been executed in restricted shell'
echo "$1"
BASH
it also works on the system with bash version 4.
Does anyone have an idea what could be the reason?
pedral
(121 rep)
Apr 10, 2024, 09:00 AM
• Last activity: Apr 10, 2024, 09:54 AM
5
votes
3
answers
2241
views
"Here Document" as a Single Line Command?
I have this command to run a checksum in some software I want to install: echo "85762db0edc00ce19a2cd5496d1627903e6198ad850bbbdefb2ceaa46bd20cbd install.sh" | sha256sum -c But I would like to use it with the `sha256sum` command *first*. So we have that using heredoc: sha256sum -c << EOF 85762db0edc0...
I have this command to run a checksum in some software I want to install:
echo "85762db0edc00ce19a2cd5496d1627903e6198ad850bbbdefb2ceaa46bd20cbd install.sh" | sha256sum -c
But I would like to use it with the
sha256sum
command *first*. So we have that using heredoc:
sha256sum -c << EOF
85762db0edc00ce19a2cd5496d1627903e6198ad850bbbdefb2ceaa46bd20cbd install.sh
EOF
But now I would like this to be all on one line... So I tried:
sha256sum -c << EOF ; 85762db0edc00ce19a2cd5496d1627903e6198ad850bbbdefb2ceaa46bd20cbd install.sh ; EOF
And it doesn't work. But _shouldn't_ it work if the semicolon ;
means "we're going to run another command"?
Can we get it in that order, but written a different way to work on one line? If not, why can't we tell it what to do on each multiple line, but on one line?
Cnnewb
(51 rep)
Mar 29, 2024, 07:38 PM
• Last activity: Apr 1, 2024, 08:34 AM
5
votes
1
answers
328
views
How can I pass variables to a file printed from outside a bash script?
Assuming I have a variable `v="c d e f g"` and a file with the content: line1 $v line3 How can I make a bash script print this file with the content of the variable in line 2 as if I was using a here-document like this: #!/bin/bash v="c d e f g" cat << EOF line1 $v line3 EOF Output: line1 c d e f g...
Assuming I have a variable
v="c d e f g"
and a file with the content:
line1
$v
line3
How can I make a bash script print this file with the content of the variable in line 2 as if I was using a here-document like this:
#!/bin/bash
v="c d e f g"
cat << EOF
line1
$v
line3
EOF
Output:
line1
c d e f g
line3
nath
(6094 rep)
Mar 29, 2024, 09:11 AM
• Last activity: Mar 29, 2024, 02:18 PM
0
votes
1
answers
125
views
How to combine ...if $x and a here-doc in perl?
How is one supposed to write this? ``` print <<EOF; if $x bla EOF ``` I think it is called postfix notation, and a here-doc. I get a syntax error. OK, I guess I'll just use ``` print "bla" if $x; ``` which, yes, does what I want.
How is one supposed to write this?
print <
I think it is called postfix notation, and a here-doc. I get a syntax error.
OK, I guess I'll just use
print "bla" if $x;
which, yes, does what I want.
Dan Jacobson
(560 rep)
Feb 14, 2024, 12:01 PM
• Last activity: Feb 14, 2024, 12:20 PM
129
votes
10
answers
72932
views
Can't indent heredoc to match code block's indentation
If there's a "First World Problems" for scripting, this would be it. I have the following code in a script I'm updating: if [ $diffLines -eq 1 ]; then dateLastChanged=$(stat --format '%y' /.bbdata | awk '{print $1" "$2}' | sed 's/\.[0-9]*//g') mailx -r "Systems and Operations " -s "Warning Stale BB...
If there's a "First World Problems" for scripting, this would be it.
I have the following code in a script I'm updating:
if [ $diffLines -eq 1 ]; then
dateLastChanged=$(stat --format '%y' /.bbdata | awk '{print $1" "$2}' | sed 's/\.[0-9]*//g')
mailx -r "Systems and Operations " -s "Warning Stale BB Data" jadavis6@[redacted].edu <EOI on a new line and break indentation patterns or
2. Keep with indentation but use something like an echo statement to get mailx to suck up my email.
I'm open to alternatives to heredoc, but if there's a way to get around this it's my preferred syntax.
Bratchley
(17244 rep)
May 20, 2013, 05:47 PM
• Last activity: Jan 18, 2024, 12:47 PM
0
votes
2
answers
63
views
Testing for dir via ssh script - nothing happens
I usually run server scripts like this, with a here-document. But when I test if a directory exists, the script continues even though the test fails -- why? ```bash ssh $user@$ip /bin/bash ~/error.txt exit 1 fi SCRIPT ``` I run this from my local computer and the server in question is a VM.
I usually run server scripts like this, with a here-document.
But when I test if a directory exists, the script continues even though the test fails -- why?
ssh $user@$ip /bin/bash ~/error.txt
exit 1
fi
SCRIPT
I run this from my local computer and the server in question is a VM.
Vinn
(236 rep)
Jan 9, 2024, 04:16 PM
• Last activity: Jan 10, 2024, 06:41 PM
143
votes
3
answers
112036
views
How do you use output redirection in combination with here-documents and cat?
Let's say I have a script that I want to pipe to another command or redirect to a file (piping to `sh` for the examples). Assume that I'm using bash. I could do it using `echo`: echo "touch somefile echo foo > somefile" | sh I could also do almost the same thing using `cat`: cat somefile EOF But if...
Let's say I have a script that I want to pipe to another command or redirect to a file (piping to
sh
for the examples). Assume that I'm using bash.
I could do it using echo
:
echo "touch somefile
echo foo > somefile" | sh
I could also do almost the same thing using cat
:
cat somefile
EOF
But if I replace "EOF" with "EOF | sh" it just thinks that it's a part of the heredoc.
How can I make it so that cat
outputs text from stdin, and then pipes it to an arbitrary location?
strugee
(15371 rep)
Aug 28, 2013, 04:41 AM
• Last activity: Dec 18, 2023, 03:02 AM
10
votes
5
answers
36379
views
pass variable in ssh
I'm trying to pass a variable to ssh remote but not works. My code is: #!/bin/bash set -x conexion="user@xx.yy.zz.pp" parameter="$1" ssh -T $conexion <<'ENDSSH' clear echo "$parameter" ENDSSH I execute: ./script.sh try It says me: parameter: Undefined variable. any help please?
I'm trying to pass a variable to ssh remote but not works. My code is:
#!/bin/bash
set -x
conexion="user@xx.yy.zz.pp"
parameter="$1"
ssh -T $conexion <<'ENDSSH'
clear
echo "$parameter"
ENDSSH
I execute:
./script.sh try
It says me:
parameter: Undefined variable.
any help please?
user650034
(163 rep)
Jul 29, 2016, 08:40 AM
• Last activity: Dec 14, 2023, 09:26 AM
20
votes
3
answers
6863
views
How to combine Bash's process substitution with HERE-document?
In Bash version 4.2.47(1)-release when I try to catenate formatted text that comes from a HERE-dcoument like so: cat <(fmt --width=10 <<FOOBAR (I want the surrounding parentheses to be part of the HERE-document) (Even the preceding unbalanced parenthesis should be part of it. FOOBAR ) # I want this...
In Bash version 4.2.47(1)-release when I try to catenate formatted text that comes from a HERE-dcoument like so:
cat <(fmt --width=10 <<'FOOBAR', because I still want to have variables being substituted within it.
Tim Friske
(2390 rep)
Jun 17, 2014, 12:49 AM
• Last activity: Oct 17, 2023, 11:25 AM
7
votes
1
answers
4302
views
How can I run patch through a heredoc in bash?
I'm trying to patch a file like this in bash: cat --- urancid 2017-12-06 09:56:33.000000000 -0600 patch --dry-run > +++ /tmp/urancid 2017-12-06 15:06:57.000000000 -0600 > @@ -393,7 +393,7 @@ > last if (/^$prompt/); > next if (/-ac\.\s*/); > next if (/-fs\.\s*/); > - next if (/set date\s*/) > + next...
I'm trying to patch a file like this in bash:
cat --- urancid 2017-12-06 09:56:33.000000000 -0600 patch --dry-run
> +++ /tmp/urancid 2017-12-06 15:06:57.000000000 -0600
> @@ -393,7 +393,7 @@
> last if (/^$prompt/);
> next if (/-ac\.\s*/);
> next if (/-fs\.\s*/);
> - next if (/set date\s*/)
> + next if (/set date\s*/);
> next if (/^(\s*|\s*$cmd\s*)$/);
> if ( ! /^$prompt/) {
> if ( ! $skipprocess ) {
> EOF
but all I get is
patching file urancid
Hunk #1 FAILED at 393.
1 out of 1 hunk FAILED -- saving rejects to file urancid.rej
Seems like it should be possible, if I cat the patch file I'm pasting it works.
I want to do this so I can make a patch script without including multiple files.
I'm not too familiar with the what "patch" cares about as far, guessing there's some whitespace problems?
Peter Turner
(1734 rep)
Dec 6, 2017, 09:21 PM
• Last activity: Jul 15, 2023, 08:59 AM
2
votes
3
answers
1400
views
How will the shell expand an include in a here-doc?
I have a case of twisted shell logic to submit to you, since I have found nothing on that particular point anywhere (please accept my apologies if I missed it). I'll try to explain the context as best I can. I have a first `scriptA` which I expect to generate a second `scriptB` through the use of a...
I have a case of twisted shell logic to submit to you, since I have found nothing on that particular point anywhere (please accept my apologies if I missed it).
I'll try to explain the context as best I can.
I have a first
scriptA
which I expect to generate a second scriptB
through the use of a heredoc. There are two items I want to have in this heredoc: a my_source
file include, and some variables local to scriptA
(for expansion within scriptA
, that is). Here is an example:
scriptA:
#!/bin/sh
logfile=/path/to/my_logfile
scriptB=/path/to/my_script
cat > ${scriptB} parameter expansion, command substitution, and arithmetic expansion
The .
is a shell special built-in utility, which is not expanded (just like all shell built-ins, including bash-, ksh-, tcsh-specific (...) built-ins).
Thanks @ilkkachu for the insight.
Meeshkah
(23 rep)
Mar 30, 2017, 09:30 AM
• Last activity: Jun 25, 2023, 02:51 PM
0
votes
0
answers
836
views
How to use heredoc inside my ssh command
I have a bash script that connects to a remote machine via SSH and runs a series of commands. It seems that the heredoc within the outer script is not aligning properly, and I keep getting an error. -bash: line 49: warning: here-document at line 6 delimited by end-of-file (wanted `MOD') This is the...
I have a bash script that connects to a remote machine via SSH and runs a series of commands.
It seems that the heredoc within the outer script is not aligning properly, and I keep getting an error.
-bash: line 49: warning: here-document at line 6 delimited by end-of-file (wanted `MOD')
This is the script:
ssh -i "$master_private_key" "$master_username@$master_public_ip" << EOF
# disable swap
sudo swapoff -a
sudo sed -i '/swap/ s/^/#/' /etc/fstab
# setup the bridge for IPV4
cat <<- MOD | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
MOD
sudo modprobe overlay
sudo modprobe br_netfilter
# sysctl params required by setup, params persist across reboots
cat <<- MOD | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
MOD
# Apply sysclt parameters without reboot
sudo sysctl --system
sudo apt-get update && apt install docker.io -y
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo mkdir /etc/apt/keyrings
sudo curl -fsSLo /etc/apt/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
# initialize kubeadm on master
kubeadm init --pod-network-cidir=192.168.0.0/16 --ignore-preflight-errors=all
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# install calico SDN
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/tigera-operator.yaml
curl https://raw.githubusercontent.com/projectcalico/calico/v3.25.0/manifests/custom-resources.yaml -O
kubectl create -f custom-resources.yaml
# Get the join command
$JOIN_COMMAND=$(kubeadm token create --print-join-command)
export $JOIN_COMMAND
EOF
I am hoping for a pointer to the issue.
George Udosen
(1917 rep)
Jun 23, 2023, 03:25 PM
• Last activity: Jun 23, 2023, 05:47 PM
Showing page 1 of 20 total questions