Create an auto-installer using curl and how to pass the args? - bash

rvm installer uses curl to install rvm. Copy from rvm official website, the command is
curl -L https://get.rvm.io | bash -s stable --autolibs=enabled [--ruby] [--rails] [--trace].
Getting the idea from this, I want to create an auto-installer using curl as well. This is my installer script fetch.sh:
#!/usr/bin/env bash
# Copyright Ciel 2014
FLAG=$#
echo 'FLAG has been set to -ns '$FLAG
git clone --recursive https://github.com/imwithye/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
./install.sh $FLAG
And I try to install my program via \curl -sSL http://dot.ciel.im | bash $FLAG(http://dot.ciel.im points to my fetch.sh script). As you can see, I want to pass the args $FLAG from curl command to fetch.sh script, but it failed.
Does anyone know how can I pass the args from curl command *** | bash $FLAG to the installer script?

What you want is :
echo "$(curl -sSL http://dot.ciel.im)" | bash -s FLAG1 FLAG2 etc
The echo with quotes is important for not being interpreted as a single line. Then, the bash -s allows you to add arguments to the script bash is executing.
you can also add -x to debug and see what commands are called and with which parameters.
echo "$(curl -sSL http://dot.ciel.im)" | bash -x -s FLAG1 FLAG2 etc

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 get the second word of an output from a command in shell?

Hi I am trying to make a shell script.
sudo usermod -s $(whereis -b zsh) $(whoami)
$(whereis -b zsh) makes an error with zsh: command not found zsh:
The error seems to occur because the output of whereis -b zsh is zsh: /usr/bin/zsh /usr/lib/x86_64-linux-gnu/zsh /bin/zsh /etc/zsh /usr/share/zsh /home/linuxbrew/.linuxbrew/bin/zsh
Now I would like to use /usr/bin/zsh for the script as an output. Is there any way to get the second word from the output of whereis -b zsh?
how should the script look like to get what I need?
shell script is quite difficult than I thought. Thank you everyone in advance!
Better add quotes around commands expansion
sudo usermod -s "$(whereis zsh | cut -d ' ' -f2)" "$(whoami)"
Alternate method by getting zsh from the $PATH:
sudo usermod -s "$(command -v zsh)" "$(id -un)"
If you run it under bash:
Instead of parsing the output of whereis, use type:
sudo usermod -s "$(type -P zsh)" "$(whoami)"
Don't forget that type -P yields an empty string, if the program you are searching for is not in the PATH.
If it is not bash, you can also do a
sudo usermod -s "$(which zsh)" "$(whoami)"
Note that which issues an error message if the program can't be found, so if you need an empty output in this case you'll have to throw away stderr.
UPDATE: Thinking of it, IMO a better solution is the one suggested by Lea Gris: command -v is available on bash and POSIX shells, and yields empty output if the file can't be found.
You can do something like:
whereis -b zsh | awk '{print $2}'

How can I verify curl response before passing to bash -s?

I have a script that looks like:
curl -sSL outagebuddy.com/path/linux_installer | bash -s
Users can install a linux client for the site using the command that is provided to them. I'm thinking there should be an intermediary step that verifies the curl had a 2XX response and downloaded the content successfully before passing it to bash. How can I do that?
Without a user-managed temporary file:
if script=$(curl --fail -sSL "$url"); then
bash -s <<<"$script"
fi
If you don't mind having an intermediate file (which you certainly need if you want to make sure the curl command worked fully) then you can use:
if curl --fail -sSL <params> -o script.sh
then
bash script.sh
fi

bash config file from remote source with an argument [duplicate]

Say I have a file at the URL http://mywebsite.example/myscript.txt that contains a script:
#!/bin/bash
echo "Hello, world!"
read -p "What is your name? " name
echo "Hello, ${name}!"
And I'd like to run this script without first saving it to a file. How do I do this?
Now, I've seen the syntax:
bash < <(curl -s http://mywebsite.example/myscript.txt)
But this doesn't seem to work like it would if I saved to a file and then executed. For example readline doesn't work, and the output is just:
$ bash < <(curl -s http://mywebsite.example/myscript.txt)
Hello, world!
Similarly, I've tried:
curl -s http://mywebsite.example/myscript.txt | bash -s --
With the same results.
Originally I had a solution like:
timestamp=`date +%Y%m%d%H%M%S`
curl -s http://mywebsite.example/myscript.txt -o /tmp/.myscript.${timestamp}.tmp
bash /tmp/.myscript.${timestamp}.tmp
rm -f /tmp/.myscript.${timestamp}.tmp
But this seems sloppy, and I'd like a more elegant solution.
I'm aware of the security issues regarding running a shell script from a URL, but let's ignore all of that for right now.
source <(curl -s http://mywebsite.example/myscript.txt)
ought to do it. Alternately, leave off the initial redirection on yours, which is redirecting standard input; bash takes a filename to execute just fine without redirection, and <(command) syntax provides a path.
bash <(curl -s http://mywebsite.example/myscript.txt)
It may be clearer if you look at the output of echo <(cat /dev/null)
This is the way to execute remote script with passing to it some arguments (arg1 arg2):
curl -s http://server/path/script.sh | bash /dev/stdin arg1 arg2
For bash, Bourne shell and fish:
curl -s http://server/path/script.sh | bash -s arg1 arg2
Flag "-s" makes shell read from stdin.
Use:
curl -s -L URL_TO_SCRIPT_HERE | bash
For example:
curl -s -L http://bitly/10hA8iC | bash
Using wget, which is usually part of default system installation:
bash <(wget -qO- http://mywebsite.example/myscript.txt)
You can also do this:
wget -O - https://raw.github.com/luismartingil/commands/master/101_remote2local_wireshark.sh | bash
The best way to do it is
curl http://domain/path/to/script.sh | bash -s arg1 arg2
which is a slight change of answer by #user77115
You can use curl and send it to bash like this:
bash <(curl -s http://mywebsite.example/myscript.txt)
I often using the following is enough
curl -s http://mywebsite.example/myscript.txt | sh
But in a old system( kernel2.4 ), it encounter problems, and do the following can solve it, I tried many others, only the following works
curl -s http://mywebsite.example/myscript.txt -o a.sh && sh a.sh && rm -f a.sh
Examples
$ curl -s someurl | sh
Starting to insert crontab
sh: _name}.sh: command not found
sh: line 208: syntax error near unexpected token `then'
sh: line 208: ` -eq 0 ]]; then'
$
The problem may cause by network slow, or bash version too old that can't handle network slow gracefully
However, the following solves the problem
$ curl -s someurl -o a.sh && sh a.sh && rm -f a.sh
Starting to insert crontab
Insert crontab entry is ok.
Insert crontab is done.
okay
$
Also:
curl -sL https://.... | sudo bash -
Just combining amra and user77115's answers:
wget -qO- https://raw.githubusercontent.com/lingtalfi/TheScientist/master/_bb_autoload/bbstart.sh | bash -s -- -v -v
It executes the bbstart.sh distant script passing it the -v -v options.
Is some unattended scripts I use the following command:
sh -c "$(curl -fsSL <URL>)"
I recommend to avoid executing scripts directly from URLs. You should be sure the URL is safe and check the content of the script before executing, you can use a SHA256 checksum to validate the file before executing.
instead of executing the script directly, first download it and then execute
SOURCE='https://gist.githubusercontent.com/cci-emciftci/123123/raw/123123/sample.sh'
curl $SOURCE -o ./my_sample.sh
chmod +x my_sample.sh
./my_sample.sh
This way is good and conventional:
17:04:59#itqx|~
qx>source <(curl -Ls http://192.168.80.154/cent74/just4Test) Lord Jesus Loves YOU
Remote script test...
Param size: 4
---------
17:19:31#node7|/var/www/html/cent74
arch>cat just4Test
echo Remote script test...
echo Param size: $#
If you want the script run using the current shell, regardless of what it is, use:
${SHELL:-sh} -c "$(wget -qO - http://mywebsite.example/myscript.txt)"
if you have wget, or:
${SHELL:-sh} -c "$(curl -Ls http://mywebsite.example/myscript.txt)"
if you have curl.
This command will still work if the script is interactive, i.e., it asks the user for input.
Note: OpenWRT has a wget clone but not curl, by default.
bash | curl http://your.url.here/script.txt
actual example:
juan#juan-MS-7808:~$ bash | curl https://raw.githubusercontent.com/JPHACKER2k18/markwe/master/testapp.sh
Oh, wow im alive
juan#juan-MS-7808:~$

what exactly does the rvm install command do

On the rvm website the installation command is:
$\curl -sSL https://get.rvm.io | bash
I dont know what does the leading \ do? My first thought will be escape, but I am not sure what it is escaping for?
Escaping would disable any aliases that might have been set up.
Consider the following example:
$ alias curl="echo hey" # alias curl
$ curl -sSL https://get.rvm.io # executing curl invoked the alias
hey -sSL https://get.rvm.io
On the other hand, escaping curl would execute the binary curl instead of any alias that might exist.

Resources