bash and nohup capture - bash

I have an scp script that looks like this:
#!/bin/bash
scp -r /usr/local/htdocs/$1 httpd#$2:/local/htdocs
I want to call it from the command line, and pass a directory, and destination server, similar to this:
move_site.sh website servername
However, I want to capture the output in a file containing the 2 parameters.
So I tried this, but it didn't print anything when calling using nohup
#!/bin/bash
scp -r /usr/local/htdocs/$1 httpd#$2:/local/htdocs > $1$1.out
How can I structure both the script and the calling command so that it runs in the background, and captures the output based on destination and site?

Your script should work, but maybe there is an error while trying to scp, that's why your output file is empty? To capture error messages to output file aswell, change > to >&:
#!/bin/bash
scp -r /usr/local/htdocs/$1 httpd#$2:/local/htdocs >& $1$2.out
To run your script in background, simply add & at the end of a command:
move_site.sh website servername &
P.S. website and servername should not include any characters, that are not allowed in a file name if you insist on using them in $1$2.out form.

If you want to pass two or more words as a single parameter, you have to wrap it with quotes:
$ cat s.sh
#!/bin/bash
echo "param1: $1, param2: $2"
So we get:
$ ./s.sh "a b" c
param1: a b, param2: c
Following this example, you have to adapt your script in consequence.

Related

Bash - SSH to remote server and retrieve data

I have a bash script that needs to connect to another server for parts of it's execution. I have tried many of the standard instructions and syntaxes for executing ssh commands, but with little progress.
On the remote server, I need to source a shell script that contains several env parameters for some software. One of these parameters are then used in a filepath to point to an executable, which contains a function ' -lprojects ' that can list the projects for the software on that server.
I have verified that running the commands on the server itself works multiple times. My issue is when I try to run the same commands over SSH. If I use the approach where I use the env variable for the filepath, it shows that the variable is null in the filepath, giving a file/directory not found error. If I hard-code the filepath to point to the executable, it gives me an error saying that the shell script is not sourced (which I assume it needs for other functions and apis for the executable to reveal it's -lprojects function)
Here is how the code looks like somewhat:
ssh remote.server 'source /filepath/remotescript.sh'
filelist=$(ssh remote.server $REMOTEVARIABLE'/bin/executable -lprojects')
echo ${filelist[#]}
for file in $filelist
do
echo $file
ssh SERVER2 awk 'something' /filepath/"$file"/somefile.txt | sed 'something' >> filepath/values.csv;
done
As you can see, I then also need to loop through the contents of the -lprojects output in the remote.server, do some awk and sed on the files to extract the wanted text (this works), but then I need to write that back to the client (local server) values.csv file. This is more generic, as there will be several servers I have to do this for, but all of them have to write to the same .csv file. For simplicity, you can just regard this as a one remote server case, since it is vital I get it working for at least one now in the beginning.
Note that I also tried something like:
ssh remote.server << EOF
'source /filepath/remotescript.sh'
filelist=$(ssh remote.server $REMOTEVARIABLE'/bin/executable -lprojects')
EOF
But with similar results. Also placing the single-quotes in the filelist both before and after the remotevariable, etc.
How do I go about properly doing this?
To access the environment variable, you must source the script that defines the environment within the same SSH call as the one where you are using it, otherwise, you're running your commands in two different shells which are unrelated:
filelist=$(ssh remote.server 'source /filepath/remotescript.sh; $REMOTEVARIABLE/bin/executable -lprojects')
Assuming executable outputs one file name per line, you can use readarray to achieve the effect :
readarray -t filelist < <(ssh remote.server '
source /filepath/remotescript.sh
$REMOTEVARIABLE/bin/executable -lprojects
'
)
echo ${filelist[#]}
for file in $filelist
do
echo $file
ssh SERVER2 awk 'something' /filepath/"$file"/somefile.txt | sed 'something' >> filepath/values.csv;
done

SSH to pfSense and run commands

If I ssh to pfSense I have to select 8 to access the shell then I can run my commands as root.
If I create a new user I can ssh direct to the shell, but have no root access.
I'm trying to write a script that will log me in, select option 8 and then run my commands.
$rules="rules information is place in this var. 1n is used for new lines"
ssh admin#192.168.1.1 << EOF
printf "8\n"
printf $rules > /home/rules;
EOF
This fails and won't log me in or create my file.
If I change it to:
ssh -tt admin#192.168.1.1 << EOF
8
echo -e "$rules" > /home/rules;
exit
0
EOF
I get logged in but my $rules values are echoed to the screen not to the new rules file I want to create.
Any one advise how I can do this?
UPDATE
I've partially got this working by using:
printf "rules" > /home/rules the only issue with that is $rules contains a variable which isn't shown in the resulting file.
eg:
$rules="rules information is places in this var.\nis used for new lines\n$additional['rules']['local']";
is written to the file as:
rules information is places in this var.
is used for new lines
['rules']['local']
Note $additional is missing before ['rules']['local']
Any way I can include that correctly ?
I've tried adding \ before $additional, I've tried changing the var so it's not enclosed in " not ' and then updated the single quotes in the string.
Each time I end up with each line from $rules being echoed to the remote command line and not into the remote file.
Any ideas ?
Thanks
Here is what I've got:
bash-3.2$ A="coucou" B="a$Aa"; echo "${B}"
a
bash-3.2$ A="coucou" B="a${A}a"; echo "${B}"
acoucoua
bash-3.2$
So, could you try with braces {}?
more about this on this answer

Bash: Variable from file output

I use a script on my personal server to setup a few things, and I'm a bit lazy.
So instead of doing every command by hand etc I got this script:
#!/bin/bash
sshservers=(IP IP IP IP)
for sshserver in "${sshservers[#]}"
do
ssh root#$sshserver 'Foo Bar'
done
echo "done"
exit
So it takes the servers from the variable in sshservers=.
But I want it to take the IP's from a file called "servers.txt".
Though when using
sshservers=$(cat servers.txt)
This doesn't work. I have to manually insert it directly in the script.
How can I use the variable from a text file?
Thanks in advance!

Want to read variable value from remote file

In one of my bash script I want to read and use the variable value from other script which is on remote machine.
How should I go ahead to resolve this. Any related info would be helpful.
Thanks in advance!
How about this (which is code I cannot currently test myself):
text=$(ssh yourname#yourmachine 'grep uploadRate= /root/yourscript')
It assumes that the value of the variable is contained in one line. The variable text now contains you variable assignment, presumably something like
uploadRate=1MB/s
There are several ways to convert the text/code into a real variable assignment in your current script, like evaluating the string or using grep. I would recommend
uploadRate=${text#*=}
to just remove the part up and including the =.
Edit: One more caveat to mention is that this only works if the original assignment does not contain variable references itself like in
uploadRate=1000*${kB}/s
ssh user#machine 'command'
will print the standard output of the remote command.
I would tell two ways at least:
1) You can simply redirect output to a file from remote server to your system with scp command...It would work for you.Then your script on your machine should read that file as an argument...
script on your machine:
read -t 50 -p "Waiting for argumet: " $1
It waits for output from remote machine,
Then you can
sshpass -p<password> scp user#host:/Path/to/file /path/to/script/
What you need to do:
You should tell the script from your machine, that the output from scp command is the argument($1)
2)Run script from your machine:
#!/bin/bash
script='
#Your commands
'
sshpass -p<password> ssh user#host $script
And you have also another ways to run script to do sth with remote machine.

Redirect text into a script that typically accepts file redirects

We have a custom script that we can run by redirecting a temporary file to that script...
i.e.
Step 1
BASH#echo 'commands' > file
Step 2
BASH#script < file
Is there a way to simplify the process to only one step... and directly send the commands to the script without the use of the temporary file?
I have attempted to do the following:
BASH# script < echo 'commands'
BASH# script < 'commands'
BASH# script < "commands"
But I always get a message that it cannot find the file specified...
Any help would be much appreciated
Have you tried just
echo 'commands' | script
?
You can also use a here-document:
script <<END_COMMANDS
commands
END_COMMANDS
Or if you only need to send one line (and are using bash):
script <<<"command"

Resources