What is | bash - - bash

What exactly does | bash - at the end of the first line of this code do in a Dockerfile?
Why the - at the end?
RUN curl --silent --location https://rpm.nodesource.com/setup_4.x | bash -
RUN yum install -y tar nodejs

The | bash means to pipe the output from the curl command, i.e. the downloaded bash script, as input to the bash command. The - makes bash read the script from stdin instead of from a file.
In other words, the command downloads a script and executes it with bash.

Related

How can I add arguments to a piped script in fish shell?

I am looking for a way to add arguments to a piped curl script which shall be executed in a fish shell. In my case, this is installation of oh-my-fish via curl.
The command without arguments is:
curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install | fish
But as I want to run this in a non interactive environment, I want to add the arguments --noninteractive and --yes to the downloaded script to get something like
curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install | fish -- --noninteractive --yes
This code is just to express, what I want and does not run.
For bash the equivalent would be
curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install | bash -s -- --noninteractive --yes
but I cannot find a way to do this with fish.
Tell fish to source stdin with arguments explicitly:
curl | fish -c 'source - --noninteractive --yes'
The - as the filename stands for stdin, any further arguments to source will be used as the $argv, no -- is necessary.
Alternatively, separate the download and running step:
curl > file
fish file --noninteractive --yes
Fish stops processing its own arguments after the filename so, again, no -- necessary.
Or, for your problem at hand, oh-my-fish reads the variables "NONINTERACTIVE" and "ASSUME_YES", so you can do
curl | NONINTERACTIVE=1 ASSUME_YES=1 fish

How to keep a bash script open with wget or curl while executing and piping it to bash

I'm trying to execute a bin script directly from a remote repository using either wget or curl. However when I run wget -O - https://raw.githubusercontent.com/matriarx/typescript/main/bin/init | bash or curl -L https://raw.githubusercontent.com/matriarx/typescript/main/bin/init | bash it immediately closes off the script and exits it.
Inside that script I'm using a read command to get user input, but it never ends up reading the input and just exits the script before ever completing it.
How can I use the wget or curl commands to get the file, pipe it to bash and keep it running and open and fully complete the script before exiting.
Try, with curl,
curl --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/matriarx/typescript/main/bin/init | sh

Passing Flags to a Piped Script [duplicate]

This question already has answers here:
Pass args for script when going thru pipe
(3 answers)
Closed 9 months ago.
I have written a shell script to configure a development environment and and retrieving using cURL. The script takes up to 3 flags, -d, -f and -s.
How do I pass the flags to the shell script?
Here is the command to run the bash script:
$ curl -sL https://example.com/setup.sh | bash
Here is my first (failed) attempt to pass flags to the script:
$ curl -sL https://example.com/setup.sh | bash -dfs
bash: -d: invalid option
Can anyone explain how to do this?
Use the -s argument:
curl -sL https://example.com/setup.sh | bash -s -- -dfs

Bash script gets printed instead of being executed

This question is similar to this one: https://serverfault.com/questions/342697/prevent-sudo-apt-get-etc-from-swallowing-pasted-input-to-stdin but the answer is not satisfying (appending && to each line of bash script is not elegant) and does not explain why some users can paste/execute multiple subsequent apt-get install -y commands and others can't because stdout is swollen by the next command.
I have a script my_script.sh:
sudo apt-get install -y graphicsmagick
sudo apt-get install -y libgraphicsmagick++1-dev
...
It can have only two lines or more of sudo apt-get install stuff. The libraries (graphicsmagick, etc.) doesn't matter, it can be any library.
When I copy this script and paste it's contents to bash or just execute it like this:
cat my_script.sh | sudo -i bash
then for some reason only the first line (graphicsmagick) gets executed and the rest is just printed to the console. It happens only with sudo apt-get install -y, other scripts, which doesn't contain this command behave normally.
If I change bash to sh (which is dash) I get expected behaviour:
cat my_script.sh | sudo -i sh
Can you explain why this happens?
When answering, can you please avoid this questions/comments:
Why are you doing it this way?
Piping to your bash is not safe
Some other aspects are not safe or hackish
I just want to know why bash doesn't work as I would expect and sh does.
PS. I'm using Ubuntu 14.04, sh is dash as you can see here:
vagrant#vagrant-ubuntu-trusty-64:/tmp$ ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 19 2014 /bin/sh -> dash
Bash and dash simply behave different when using -i flag.
Bash always goes to interactive mode even when stdin is not a terminal.
Dash on the other hand will not go into interactive mode, even with -i flag.
Probably need the -s option
If the -s option is present, or if no arguments remain after option
processing, then commands are read from the standard input. This option allows
the positional parameters to be set when invoking an interactive shell.
Bash man page
curl -s http://foo.com/bar.sh | sudo -i bash -s
Example

Redirect output from a shell script to a file

I'm busy writing up a Capistrano deployment script for one of our applications. One of the steps installs RVM using the following command:
run "cat ~/rvm-installer.sh | bash -s stable --ruby"
However, I feel the output is too verbose, and I rather want to dump it into a .log file. Is it possible to redirect the output for the entire rvm-installer.sh script elsewhere?
Like this:
run "cat ~/rvm-installer.sh | bash -s stable --ruby >out.log"
or, if you want to redirect standard error stream of the process as well:
run "cat ~/rvm-installer.sh | bash -s stable --ruby >out.log 2>err.log"
you can also redirect everything to the same file:
run "cat ~/rvm-installer.sh | bash -s stable --ruby >out.log 2>&1"

Resources