This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

[email protected] - Bash v3 task
- 5 minutes to read
- 2 contributors
Use this task to run a Bash script on macOS, Linux, or Windows.
targetType - Type string . Allowed values: filePath (File Path), inline . Default value: filePath .
Targets script type: file path or inline.
filePath - Script Path string . Required when targetType = filePath .
The path of the script to execute. This must be a fully qualified path or relative to $(System.DefaultWorkingDirectory) .
arguments - Arguments string . Optional. Use when targetType = filePath .
The arguments passed to the shell script. Either ordinal parameters or named parameters.
script - Script string . Required when targetType = inline . Default value: # Write your commands here\n\necho 'Hello world' .
The contents of the script.
script - Script string . Required when targetType = inline . Default value: # Write your commands here\n\n# Use the environment variables input below to pass secret variables to this script .
script - Script string . Required when targetType = inline . Default value: # Write your commands here .
workingDirectory - Working Directory string .
Specifies the working directory in which you want to run the command. If you leave it empty, the working directory is $(Build.SourcesDirectory) .
failOnStderr - Fail on Standard Error boolean . Default value: false .
If this is true, this task will fail if any errors are written to the StandardError stream.
bashEnvValue - Set value for BASH_ENV environment variable string .
If the input is specified, its value is expanded and used as the path of a startup file to execute before running the script. If the environment variable BASH_ENV has already been defined, the task will override this variable only for the current task. Learn more about Bash Startup Files .
noProfile - Don't load the profile startup/initialization files boolean . Default value: true .
Don't load the system-wide startup file /etc/profile or any of the personal initialization files.
noRc - **Don't read the ~/.bashrc' initialization file**<br> boolean . Default value: true`.
Task control options
All tasks have control options in addition to their task inputs. For more information, see Control options and common task properties .
Output variables
The bash task has a shortcut in YAML: steps.bash .
The Bash task will find the first Bash implementation on your system. Running which bash on Linux/macOS or where bash on Windows will give you an idea of which one it will select.
Info about Bash startup files
The Bash task invokes the Bash as a non-interactive, non-login shell. When Bash is started non-interactively, to run a shell script, the Bash looks for the variable BASH_ENV in the environment, unfolds its value if it appears there, and uses the value as the name of a file to read and execute.
There are several options for defining the BASH_ENV environment variable in a pipeline. Firstly, it's possible to set the BASH_ENV environment variable as a pipeline variable. In this case, each instance of the Bash task will try to unfold the value of the BASH_ENV variable and use its value.
Another option is to set BASH_ENV for one particular instance of the Bash task, there are two ways how this can be done:
The first way is to use the bashEnvValue task input, see an example for reference:
Another way is to set the BASH_ENV variable as an environment variable for the pipeline task via the env keyword, for example:
Note that if the bashEnvValue input is defined in the Bash task, the pipeline task will override the value of the BASH_ENV variable with the value from the bashEnvValue input in a case when the BASH_ENV environment variable was already defined in the environment.
Bash scripts checked into the repo should be set executable ( chmod +x ). Otherwise, the task will show a warning and source the file instead.
You can map in variables using the env parameter which is common across all tasks , and is list of additional items to map into the process's environment. For example, secret variables are not automatically mapped. If you have a secret variable called Foo , you can map it in like this:
On macOS or Linux, the example above is equivalent to:
Requirements
Submit and view feedback for
Additional resources
Stack Exchange Network
Stack Exchange network consists of 181 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Super User is a question and answer site for computer enthusiasts and power users. It only takes a minute to sign up.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Linux Bash Script, Single Command But Multiple Lines?
I have the following script I wrote by searching Google, and it backs up my Linux system to an archive:
This works, but I am wondering if I can format the script to show the command over multiple lines, something like this, so it is easy to edit later:
That way it is easier to read and edit later. Is it possible to format a Bash script this way?
5 Answers 5
All you should need to do is add "\" at the end of each line and it should be good to go.
So yours will look like:
A Few Shortcuts
(based on your comment update for setting $HOSTNAME)
Two options to set that:
Set HOSTNAME
HOSTNAME=$(hostname)
Use command substitution (e.g. $(command) )
So it would look like above. That just makes the command run before using it.
Another variable avoided would be easily:
$ man date will have the formats for the date options, the above is YYYYmmdd
- Thanks guys. One last thing. There seems to be a problem with the file name portion of my script: $HOSTNAME_$DATE.tar.gz When I run the script now, the output file is: 20121120.tar.gz – Jay LaCroix Nov 21, 2012 at 3:26
- If you want your actual "hostname" put it in back ticks (the tilde "~" key above tab): /share/Recovery/Snapshots/`hostname`_$DATE.tar.gz – nerdwaller Nov 21, 2012 at 3:36
- Anytime @JayLaCroix - Welcome to SU! – nerdwaller Nov 21, 2012 at 3:40
- 2 It is recommended to use $(command) instead of `command` . – andrybak Jan 25, 2015 at 10:46
- This works with withspaces as a separator. If I have ssh on the first line and commands on the following lines, I think I need a semicolon as well besides backslash. – Timo Nov 22, 2020 at 8:23
Use the backslash to continue a command on the next line:
- I went back to update it to make it more useful and get the indentations. I love SU though, by and large. – nerdwaller Nov 21, 2012 at 3:35
- This doesn't work for me like eg. in alias ub='source ~/.bash_aliases \ && source $HOME/.bash_aliases \ && echo "aliases updated."'; – TheDefinitionist Oct 5, 2016 at 17:12
- 1 @TheDefinitionist Sounds like a different problem to this one. Perhaps open a new question? – Paul Oct 6, 2016 at 2:58
- 1 Can I line up the backslashes in a column on the right? – SDsolar Jul 30, 2017 at 23:45
- @SDsolar You can use spaces and tabs to line up the slashes. – Paul Jul 31, 2017 at 0:53
You can use this in bash
- 3 Should be tar "${PARAMS[@]}" , so that params with spaces get preserved. – timkay Mar 19, 2022 at 17:25
The same command, but with comments for each line, would be:
- This technique is not recommended when performances matter: "note that this technique is expensive because it creates a subshell for each of such “inline comments” during execution. It is only suitable if the commands performance or cost is not a problem." Source: systutorials.com/… – roneo.org Apr 10, 2022 at 4:54
Axel Heider provided a good alternative to backslashes. Two notes:
- The command can be included in the list, and
- The use of the list should be in double quotes "${PARAMS[@]}" , so that any spaces in parameters get preserved.
Your Answer
Sign up or log in, post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service , privacy policy and cookie policy
Not the answer you're looking for? Browse other questions tagged linux bash script tar or ask your own question .
- The Overflow Blog
- How Intuit democratizes AI development across teams through reusability sponsored post
- The nature of simulating nature: A Q&A with IBM Quantum researcher Dr. Jamie...
- Featured on Meta
- We've added a "Necessary cookies only" option to the cookie consent popup
Hot Network Questions
- Rolling cube on an infinite chessboard
- Can archive.org's Wayback Machine ignore some query terms?
- Is there a proper earth ground point in this switch box?
- Redoing the align environment with a specific formatting
- Follow Up: struct sockaddr storage initialization by network format-string
- What can a lawyer do if the client wants him to be acquitted of everything despite serious evidence?
- Replacing broken pins/legs on a DIP IC package
- Trying to understand how to get this basic Fourier Series
- Checking system vs. SEPA and the like
- Why do small African island nations perform better than African continental nations, considering democracy and human development?
- Surly Straggler vs. other types of steel frames
- Can airtags be tracked from an iMac desktop, with no iPhone?
- Does a summoned creature play immediately after being summoned by a ready action?
- Disconnect between goals and daily tasks...Is it me, or the industry?
- Acidity of alcohols and basicity of amines
- Using indicator constraint with two variables
- Seal script identification/translation
- About an argument in Famine, Affluence and Morality
- Short story taking place on a toroidal planet or moon involving flying
- Mutually exclusive execution using std::atomic?
- Calculating probabilities from d6 dice pool (Degenesis rules for botches and triggers)
- How do you get out of a corner when plotting yourself into a corner
- What is the purpose of this D-shaped ring at the base of the tongue on my hiking boots?
- OK to delete Windows.db file on PC?
Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .
- Stack Overflow Public questions & answers
- Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
- Talent Build your employer brand
- Advertising Reach developers & technologists worldwide
- About the company
Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.

How to output a multiline string in Bash?
How can I output a multipline string in Bash without using multiple echo calls like so:
I'm looking for a portable way to do this, using only Bash builtins.
- 6 If you're outputting a usage message in response to an incorrect invocation, you would normally send that message to standard error instead of standard output, with echo >&2 ... – Mark Reed Jun 10, 2012 at 17:05
- 3 @MarkReed The usage message is output by typing --help (which should go to standard out). – helpermethod Jun 12, 2012 at 10:00
- 2 For others who come along, more info about "here documents" is available: tldp.org/LDP/abs/html/here-docs.html – Jeffrey Martinez Dec 31, 2015 at 8:08
- 1 Check the printf -based solution from Gordon Davidson. Despite being in the shadow of the echo or cat based approaches, it seems to be much less of a kludge. Admittedly the `printf' syntax represent a bit of a learning curve, but I'd like to ear of other drawbacks (? compatibility, performance ? ...) – mjv Apr 26, 2017 at 23:49
- 1 Related: stackoverflow.com/questions/23929235/… – Anton Tarasenko Oct 22, 2017 at 10:03
11 Answers 11
Here documents are often used for this purpose.
They are supported in all Bourne-derived shells including all versions of Bash.
- 7 Yup - but cat isn't a built-in. – Mark Reed Jun 10, 2012 at 17:15
- 13 @MarkReed: That's true, but it's always available (except possibly under unusual circumstances). – Dennis Williamson Jun 10, 2012 at 17:17
- 9 +1 Thx. I've ended up using read -d '' help <<- EOF ... to read the multiline string into a variable and then echoed the result. – helpermethod Jun 10, 2012 at 21:11
- 4 can i save a HEREDOC to a variable? – chovy Dec 14, 2015 at 1:03
- 1 Bloody genius, thanks @DennisWilliamson! ProTip: If you need to escape the content from things like backticks/etc, you can double quote the delimiter on the first line, like cat << "EOF" . – Joshua Pinter May 3, 2022 at 21:17
or you can do this:
- 2 @OliverWeiler: It will even work in Bourne shells such as Dash and the Heirloom Bourne Shell . – Dennis Williamson Jun 10, 2012 at 17:05
- 14 Not great if you need this in a function because you'll either need to 1) outdent the string all the way to the left of your file or 2) keep it indented to line up with the rest of your code but then it prints with the indents as well – s g Oct 19, 2018 at 20:45
- 3 Works. Also note use ' (single quotes) instead of " (double quotes) if you don't want the interpretation of the string. If you want $something or something in the output instead of it getting replaced. – Eric Nov 6, 2021 at 15:03
Inspired by the insightful answers on this page, I created a mixed approach, which I consider the simplest and more flexible one. What do you think?
First, I define the usage in a variable, which allows me to reuse it in different contexts. The format is very simple, almost WYSIWYG, without the need to add any control characters. This seems reasonably portable to me (I ran it on MacOS and Ubuntu)
Then I can simply use it as
or even better, when parsing parameters, I can just echo it there in a one-liner:

- 4 this worked for me in a script where the above answer does not (without modification). – David Welch Sep 25, 2018 at 0:16
- 6 This is much cleaner than involving a bunch of characters like \t and \n which are hard to find in the text and expand to make the output much different than the string in the script – s g Oct 19, 2018 at 20:53
- 2 For some reasons it prints everything on the same line for me :/ – Nicolas de Fontenay Mar 13, 2020 at 15:36
- 2 If you use the solution from @jorge and find that everything is on the same line, make sure you enclose the variable in quotes: ``` echo $__usage ``` will print everything on one line whereas ``` echo "$__usage" ``` will retain the newlines. – user1165471 Apr 9, 2020 at 17:12
- 5 @Nicolas: Using double quotes in echo "$__usage" was necessary for me. echo $__usage did not work. – Mario Apr 10, 2020 at 10:15
Use -e option, then you can print new line character with \n in the string.
For example:
- 7 Those man pages are for the system-supplied echo command, /bin/echo , which on Mac OS has no -e option. when you're using bash on those systems, its built-in echo command takes over. You can see this by explicitly typing /bin/echo whatever and observing the difference in behavior. To see the documentation for the built-in, type help echo . – Mark Reed Jun 10, 2012 at 16:59
- 1 /bin/echo is often different from one OS to another and different from Bash's builtin echo . – Dennis Williamson Jun 10, 2012 at 17:01
- @MarkReed: I'll try later, but thanks for the info. +1. I will just leave my answer here, since there are quite a lot of good discussion going on. – nhahtdh Jun 10, 2012 at 17:01
- 8 echo -e is not portable -- for example, some implementations of echo will print the "-e" as part of the output. If you want portability, use printf instead. For example, /bin/echo on OS X 10.7.4 does this. IIRC the bash builtin echo was also weird under 10.5.0, but I don't remember the details any more. – Gordon Davisson Jun 10, 2012 at 17:02
- 2 echo -e has bitten me before... Definitely use printf or cat with a heredoc. The <<- variant of here docs are especially nice because you can strip leading indentation in the output, but indent for readability in the script – zbeekman Jun 7, 2017 at 2:10
Since I recommended printf in a comment, I should probably give some examples of its usage (although for printing a usage message, I'd be more likely to use Dennis' or Chris' answers). printf is a bit more complex to use than echo . Its first argument is a format string, in which escapes (like \n ) are always interpreted; it can also contain format directives starting with % , which control where and how any additional arguments are included in it. Here are two different approaches to using it for a usage message:
First, you could include the entire message in the format string:
Note that unlike echo , you must include the final newline explicitly. Also, if the message happens to contain any % characters, they would have to be written as %% . If you wanted to include the bugreport and homepage addresses, they can be added quite naturally:
Second, you could just use the format string to make it print each additional argument on a separate line:
With this option, adding the bugreport and homepage addresses is fairly obvious:
Also with indented source code you can use <<- (with a trailing dash) to ignore leading tabs (but not leading spaces).
For example this:
Outputs indented text without the leading whitespace:

- That did not work for me. What shell are you using? – four43 Jun 11, 2019 at 22:55
- Did not work in bash 4.4.19 in Ubuntu. It did not remove the spacing before line1 and line2 – four43 Jun 12, 2019 at 20:22
- 1 @four43, You were right. Does not work to remove leading spaces. However, does remove leading tabs. So I corrected my answer from tabs and spaces, to tabs and not spaces. Sorry for the mistake. I checked the manual and it clearly just says tabs are removed. Thanks for bringing this to my attention. – Elliptical view Jun 13, 2019 at 23:03
- It works with bash and zsh on MacOS 11.4. Great tip! – Philipp Jun 6, 2021 at 22:03
- ProTip: Use double quotes around your delimiter to escape things, like "xx" . – Joshua Pinter May 3, 2022 at 21:16
I usually go with the builtin read command which I think is more flexible and intuitive. It reads the contents of a line into a variable, and allows for word splitting that is tied to the special shell variable IFS. Refer to this blog or even the man page for more details.
- 2 Best thing about this is that <<- (with the minus sign) ignores leading tab characters so that you can indent your message inside the code without indenting it when printed. – BUFU Oct 25, 2021 at 8:24
One more thing, using printf with predefined variable (here: msg ) as template.
This ^^^ will print whole message with additional vars inserted instead of %s in provided order.
- This works well in Makefiles – John Tang Boyland May 17, 2022 at 21:44

Output withOUT calling dedent first:
...and WITH calling dedent first (as shown above):
For a full explanation, see where I've already written about this:
- Equivalent of python's textwrap dedent in bash
- Multi-line string with extra space (preserved indentation)
And of course, thanks to @Andreas Louv for showing me the sed part of that function here .
- Note: Does not preserve indentation. See also stackoverflow.com/a/63228433/724752 – David Winiecki Apr 22, 2022 at 20:32
Here is how I've done:
Your Answer
Sign up or log in, post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service , privacy policy and cookie policy
Not the answer you're looking for? Browse other questions tagged bash or ask your own question .
- The Overflow Blog
- How Intuit democratizes AI development across teams through reusability sponsored post
- The nature of simulating nature: A Q&A with IBM Quantum researcher Dr. Jamie...
- Featured on Meta
- We've added a "Necessary cookies only" option to the cookie consent popup
- Launching the CI/CD and R Collectives and community editing features for...
- Staging Ground Beta 1 Recap, and Reviewers needed for Beta 2
- The [amazon] tag is being burninated
- Temporary policy: ChatGPT is banned
Hot Network Questions
- Linear Algebra - Linear transformation question
- Seal script identification/translation
- Who owns code in a GitHub organization?
- Why does Mister Mxyzptlk need to have a weakness in the comics?
- The difference between the phonemes /p/ and /b/ in Japanese
- base table view not found
- Calculating probabilities from d6 dice pool (Degenesis rules for botches and triggers)
- Using Kolmogorov complexity to measure difficulty of problems?
- Why is there a voltage on my HDMI and coaxial cables?
- How do you ensure that a red herring doesn't violate Chekhov's gun?
- Where does this (supposedly) Gibson quote come from?
- Disconnect between goals and daily tasks...Is it me, or the industry?
- Why is this sentence from The Great Gatsby grammatical?
- What did Ctrl+NumLock do?
- How can this new ban on drag possibly be considered constitutional?
- Surly Straggler vs. other types of steel frames
- What's the difference between a power rail and a signal line?
- How do you get out of a corner when plotting yourself into a corner
- OK to delete Windows.db file on PC?
- Do new devs get fired if they can't solve a certain bug?
- How to notate a grace note at the start of a bar with lilypond?
- How to match a specific column position till the end of line?
- Largest Binary Area
- What Is the Difference Between 'Man' And 'Son of Man' in Num 23:19?
Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .
Multi-Line String in Bash

This tutorial demonstrates different ways to print a multi-line string to a file in bash without putting extra space (indentation) by the use of here-document , shell variable, printf , echo , and echo with -e option.
Use here-document to Make Multi-Line String in Bash
From the output, we see that every set of words has its own line, and there are no extra spaces.
Use Shell Variable to Make Multi-Line String in Bash
Please enable JavaScript
Use printf to Make Multi-Line String in Bash
Use echo with the -e option to make multi-line string in bash, use echo to make multi-line string in bash.
Fumbani is a tech enthusiast. He enjoys writing on Linux and Python as well as contributing to open-source projects.
Related Article - Bash String
Stack Exchange Network
Stack Exchange network consists of 181 Q&A communities including Stack Overflow , the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It only takes a minute to sign up.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Here documents as multiple lines command within the bash
I created a snippet to test the here document
It come to Here document
It works properly, Unfortunately, it's not the case of structured command
I tried alternatively
What's the problem not allow the for command working?

- What are you trying to accomplish by using loop inside heredoc? – user1700494 Oct 28, 2018 at 14:14
- learning to get a better understanding about how heredoc work. @user1700494 – AbstProcDo Oct 28, 2018 at 14:16
- You'd need to escape the special characters, e.g. * -> \* , $i -> \$i – steve Oct 28, 2018 at 14:21
- 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 ♦ Oct 28, 2018 at 15:09
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 the i variable is unset, it will expand to an empty string. You may choose to quote the here-document (by quoting the first EOF as 'EOF' or \EOF ) 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 to eval 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 is for , so bash would expect to run a shell script called for 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 is EOF) with a trailing right parenthesis, not EOF ), saying something like
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.
The first of your examples work because it's a simple command.

Your Answer
Sign up or log in, post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service , privacy policy and cookie policy
Not the answer you're looking for? Browse other questions tagged bash or ask your own question .
- The Overflow Blog
- How Intuit democratizes AI development across teams through reusability sponsored post
- The nature of simulating nature: A Q&A with IBM Quantum researcher Dr. Jamie...
- Featured on Meta
- We've added a "Necessary cookies only" option to the cookie consent popup
Hot Network Questions
- Biodiversity through radiation
- How can we prove that the supernatural or paranormal doesn't exist?
- What can a lawyer do if the client wants him to be acquitted of everything despite serious evidence?
- Counting Letters in a String
- Is there a proper earth ground point in this switch box?
- How do you get out of a corner when plotting yourself into a corner
- Is a PhD visitor considered as a visiting scholar?
- base table view not found
- How to match a specific column position till the end of line?
- Did this satellite streak past the Hubble Space Telescope so close that it was out of focus? If so, how close was it?
- Follow Up: struct sockaddr storage initialization by network format-string
- Can archive.org's Wayback Machine ignore some query terms?
- How to handle a hobby that makes income in US
- Redoing the align environment with a specific formatting
- nicematrix: add ttfamily in the last-col
- Is it possible to create a concave light?
- FAA Handbooks Copyrights
- What is the correct way to screw wall and ceiling drywalls?
- Why does Mister Mxyzptlk need to have a weakness in the comics?
- Using indicator constraint with two variables
- Linear Algebra - Linear transformation question
- How can this new ban on drag possibly be considered constitutional?
- Rolling cube on an infinite chessboard
- Using Kolmogorov complexity to measure difficulty of problems?
Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .

IMAGES
VIDEO
COMMENTS
The first way is to use the bashEnvValue task input, see an example for reference: YAML steps: - task: [email protected] inputs: targetType: 'inline' script: env bashEnvValue: '~/.profile' Another way is to set the BASH_ENV variable as an environment variable for the pipeline task via the env keyword, for example: YAML
Axel Heider provided a good alternative to backslashes. Two notes: The command can be included in the list, and; The use of the list should be in double quotes "${PARAMS[@]}", so that any spaces in parameters get preserved.
Here are two different approaches to using it for a usage message: First, you could include the entire message in the format string: printf "usage: up [--level <n>| -n <levels>] [--help] [--version] Report bugs to: up home page: ". Note that unlike echo, you must include the final newline explicitly.
Use Shell Variable to Make Multi-Line String in Bash Here, we are using a shell variable named greet. We have assigned a multi-line string to greet. greet="Hello > , > wolrd > !" The command below gets the multi-line string in the shell variable, greet, and redirects it to the specified file, multiline.txt, using >. echo "$greet" > multiline.txt
2. I would like to process a multiline string and iterate it line by line, in a POSIX shell ( /bin/sh) on a BSD platform. Bash is not included in the base BSD-distribution and has a GPL license - so I am trying to make it universally work with /bin/sh instead. I found a solution using a pipe, however in the regular /bin/sh shell, these a ...
bash: 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 ...