I'm writing a script that installs and configures Nagios to my requirements. It requires cpanm and some perl modules.
It's using the step/try/next function from here: https://stackoverflow.com/a/5196220
step "Downloading cpanm installer"
try `wget -q http://cpanmin.us -O $swrepo/cpanm.install`
next
step "Installing cpanm"
try echo '{ exec </dev/tty; cat $swrepo/cpanm.install | perl - App::cpanminus; }' | bash
# try bash -c "$(cat $swrepo/cpanm.install | perl - App::cpanminus)"
# try cat $swrepo/cpanm.install | perl - App::cpanminus
next
step "Installing Perl module Nagios Config"
try `cpanm Nagios::Config`
next
My problems here are:
whichever way I attempt to run the install for cpanminus, it fails the script, and won't install properly. I can't seem to make it function outside of the step/try/next functions (not that I want it to.)
The cpanm command fails too. If I isolate and run only this part of the script, it still fails, with "cpanm command not found." I can run it manually at the command line.
Any pointers for the slightly frustrated?
Update
I pulled the cpanm setup out to a separate file:
step "Installing cpanm"
try sh conf_cpanm.sh
next
Which works, and I'll probably try and pull it back in at a later date, but so far that functions. So it can stay.
However, doing the same for
try cpanm Nagios::Config
won't work. The file looks like this:
#!/bin/bash
cpanm Nagios::Config
...and if I run that by calling sh conf_nagcpanm.sh it works fine.
I think using backticks
try `cpanm Nagios::Config`
is a mistake. bash will take an expression in backticks, execute it, and substitute the output of the command for the expression. The output of cpanm is not going to be shell commands, so this will not work. It should simply be
try cpanm Nagios::Config
Related
I have installed libpam-google-authenticator and freeradius on server ubuntu 16.0405. Everything works good, except for if I use the command google-auth in bash script I get a error message "google-auth: command not found"
But the same works if I put it on terminal directly.
#!/bin/bash
google-auth
That is not a bash script.
To make it a bash script, your first line needs to include a "#" as follows:
#!/bin/bash
google-auth
Also, you need to ensure that the script is executable:
chmod +x yourscript.sh
Hopefully that will solve your problem.
As per the comments below, it seems like the command "google-auth" was an alias which wasn't being established in the child shell.
I am trying to have RVM and ruby installed in an Ubuntu 12 virtual machine without human interaction apart from the password prompts.
I created a shell script to do this that works pretty fine until I need to use RVM itself.
I am using multi-user installation.
#!/bin/bash -l
mainUser=`whoami`
echo "Installing as '${mainUser}'"
echo "Installing git..."
sudo -S apt-get install --yes curl git-core
echo "Installing RVM..."
\curl -L https://get.rvm.io | sudo bash -s stable
echo "Adding ${mainuser} to RVM group..."
sudo adduser $mainUser rvm
newgrp rvm
From here things get weird.. I need to load dvm as a source. I want both my script to have this source and my user's bash_profile / bashrc. Anyway.. I know how to do it manually, but I can't have this done from the script. This is the last code I tried:
. "/usr/local/rvm/bin/rvm"
rvm use ruby-head
rubyVersion=`rvm list | awk '/ruby-head/{print x;print};{x=$0}' | sed -n '/ruby-head/{g;1!p;};h' | awk -F ' ' '{print $1}'`
rubyTest=${rubyVersion}#test
rvm use $rubyTest --create --default
The error I get is this:
test.sh: 7: /usr/local/rvm/bin/rvm: Syntax error: "(" unexpected (expecting "fi")
If I simply try to use the full path, like this:
rvm=/usr/local/rvm/bin/rvm
$rvm use ruby-head
rubyVersion=`$rvm list | awk '/ruby-head/{print x;print};{x=$0}' | sed -n '/ruby-head/{g;1!p;};h' | awk -F ' ' '{print $1}'`
rubyTest =${rubyVersion}#test
$rvm use $rubyTest --create --default
I get this error instead:
RVM is not a function, selecting rubies with 'rvm use ...' will not work.
I am clueless. Why can't I use /usr/local/rvm/bin/rvm?
Is there a way to execute source /etc/profile.d/rvm.sh for this user from the script?
I am not so good at shell script and Linux, so I appreciate any references and examples you could give.
Thanks!
UPDATE
I also tried:
source "/usr/local/rvm/scripts/rvm"
... and all it's variants. Same error: "RVM is not a function".
rvm is actually implemented as a shell function rather than an executable, which is why you can't just call /usr/local/rvm/bin/rvm itself.
Quoting you, "Is there a way to execute source /etc/profile.d/rvm.sh for this user from the script?"
Have you tried doing that? I had a somewhat similar install once where it didn't work properly from crontab (they have instructions on the site for that scenario, but we couldn't make them work), and I had to do almost exactly that -- source part of the profile.d for rvm.
RVM is not a function, selecting rubies with 'rvm use ...' will not work.
Above error is generated when rvm is not running and hence your terminal is not able to recognize it, as it tries to run it as a system command.
You may want to try this to run rvm through your shell script before calling rvm methods:
source ~/.rvm/scripts/rvm
I found out what is causing the issue.
I realised before that I would get errors in the lines with conditions in the script files, so I came across this page:
https://superuser.com/questions/552016/bash-script-not-found
As it happens, I was executing the script with the following command:
sh script.sh
Which means I was getting Dash instead of Bash.
To fix the issue I changed my code to have this:
PATH=$PATH:/usr/local/rvm/bin # Add RVM to PATH for scripting
[[ -s "/usr/local/rvm/scripts/rvm" ]] && . "/usr/local/rvm/scripts/rvm" # Load RVM function
And then I executed like this:
bash script.sh
And voilĂ ... RVM works again!
I have a bash script that partially needs to be running with default user rights, but there are some parts that involve using sudo (like copying stuff into system folders) I could just run the script with sudo ./script.sh, but that messes up all file access rights, if it involves creating or modifying files in the script.
So, how can I run script using sudo for some commands? Is it possible to ask for sudo password in the beginning (when the script just starts) but still run some lines of the script as a current user?
You could add this to the top of your script:
while ! echo "$PW" | sudo -S -v > /dev/null 2>&1; do
read -s -p "password: " PW
echo
done
That ensures the sudo credentials are cached for 5 minutes. Then you could run the commands that need sudo, and just those, with sudo in front.
Edit: Incorporating mklement0's suggestion from the comments, you can shorten this to:
sudo -v || exit
The original version, which I adapted from a Python snippet I have, might be useful if you want more control over the prompt or the retry logic/limit, but this shorter one is probably what works well for most cases.
Each line of your script is a command line. So, for the lines you want, you can simply put sudo in front of those lines of your script. For example:
#!/bin/sh
ls *.h
sudo cp *.h /usr/include/
echo "done" >>log
Obviously I'm just making stuff up. But, this shows that you can use sudo selectively as part of your script.
Just like using sudo interactively, you will be prompted for your user password if you haven't done so recently.
I was recommended for this student job by one of my profs. I have never coded a shell script in my life. I have read some tutorials online about shell scripting, but that is it. Anyway, I have been asked to create a script that will run:
find-repos-of-install | grep rpmfusion
and given the output of that search, will run a yum update. Ex:
find-repos-of-install | grep rpmfusion
#that gives this output
libCg-3.1.0013-2.el6.x86_64 from repo rpmfusion-nonfree-updates
pgplot-5.2.2-34.el6.1.x86_64 from repo rpmfusion-nonfree-updates
pgplot-devel-5.2.2-34.el6.1.x86_64 from repo rpmfusion-nonfree-updates
yum update libCg pgplot pgplot-devel
That is what he wants the script to do. I'm not asking anyone to write the whole script for me, just try to point me in the right direction. I've done coding in Java, but that hasn't helped me at all, shell script looks like gibberish to me still. Thanks for any tips/hints
You have two options of how to call a command (yum in your case) with output of another command (grep in your case): one is to do something like:
$ yum update $(find-repos-of-install | grep rpmfusion)
Another one is to use xargs, something like:
$ find-repos-of-install | grep rpmfusion | xargs yum update
After designing a simple shell/bash based backup script on my Ubuntu engine and making it work, I've uploaded it to my Debian server, which outputs a number of errors while executing it.
What can I do to turn on "error handling" in my Ubuntu machine to make it easier to debug?
ssh into the server
run the script by hand with either -v or -x or both
try to duplicate the user, group, and environment of the error run in your terminal window If necessary, run the program with something like "su -c 'sh -v script' otheruser
You might also want to pipe the result of the bad command, particularly if run by cron(8), into /bin/logger, perhaps something like:
sh -v -x badscript 2>&1 | /bin/logger -t badscript
and then go look at /var/log/messages.
Bash lets you turn on debugging selectively, or completely with the set command. Here is a good reference on how to debug bash scripts.
The command set -x will turn on debugging anywhere in your script. Likewise, set +x will turn it off again. This is useful if you only want to see debug output from parts of your script.
Change your shebang line to include the trace option:
#!/bin/bash -x
You can also have Bash scan the file for errors without running it:
$ bash -n scriptname