Capture Bash output to variable in Shell Script [duplicate] - bash

This question already has answers here:
How do I set a variable to the output of a command in Bash?
(15 answers)
Closed 3 years ago.
I have written a shell script to run other shell script on remote server(Shell script is running successfully on remote server). I want to capture output to some variable. Below is my code.
Please can anyone help me out.
#! /bin/sh
sshpass -p password ssh -T root#serverIP1 << EOF
sshpass -p password ssh -T root#serverIP2 << EOS
copyoutput=bash /opt/Shellscriptlocation/DiskSpace.sh
EOS
EOF
echo $copyoutput

This should work for you by placing command substitution in outermost shell:
copyoutput=$(
sshpass -p password ssh -T root#serverIP1 << EOF
sshpass -p password ssh -T root#serverIP2 << EOS
bash /opt/Shellscriptlocation/DiskSpace.sh
EOS
EOF
)
echo "$copyoutput"

Related

Passing variables to SSH [duplicate]

This question already has answers here:
Passing external shell script variable via ssh
(2 answers)
Variable issues in SSH
(1 answer)
Closed 1 year ago.
The following code loops through states in a array and passes a state to a server via ssh -
STATES="NY CO"
arr_states=(${STATES//' /'/ })
for i in "${arr_states[#]}"; do
state=$i
ssh -o SendEnv=state jenkins#server sh -s << 'EOF'
sudo su
cd /home/jenkins/report
psql -d db -c "$(sed 's/state_name/'"$state"'/' county.sql)" -U user
echo $state
EOF
done
The output of echo $state in the above is an empty string even if I pass it NY.
When I change the 'EOF' to EOF, the output of echo $state is the string I passed (NY). But then it says, the file county.sql does not exist.
How do I get it to recognize both the variable I pass and the file on the remote I am trying to run.
As an approach that doesn't require you to do any manual escaping of your code (which frequently becomes a maintenance nightmare, since it means that code needs to be changed whenever you modify where it's expected to run) -- consider defining a function, and using declare -f to ask the shell to generate code that will output that function for you.
The same can be done with variables, using declare -p. Thus, passing both a function with the remote code, and the variables that remote code needs to operate that way:
#!/usr/bin/env bash
# This is run on the remote server _as root_ (behind sudo su)
remotePostEscalationFunc() {
cd /home/jenkins/report || return
if psql -d db -U user -c "$(sed -e "s/state_name/${state}/" county.sql)"; then
echo "Success processing $state" >&2
else
rc=$?
echo "Failure processing $state" >&2
return "$rc"
fi
}
# This is run on the remote server as the jenkins user (before sudo).
remoteFunc() {
sudo su -c "$(declare -p state); $(declare -f remotePostEscalationFunc); remotePostEscalationFunc"
}
# Everything below here is run locally.
arr_states=( NY CO )
for state in "${arr_states[#]}"; do
ssh jenkins#server 'bash -s' <<EOF
$(declare -f remoteFunc remotePostEscalationFunc); $(declare -p state); remoteFunc
EOF
done
You were almost right with the change from 'EOF' to EOF. You are just missing a backslash (\) before $(sed. So the following should work:
arr_states=(${STATES//' /'/ })
for i in "${arr_states[#]}"; do
state=$i
ssh -o SendEnv=state jenkins#server sh -s << EOF
sudo su
cd /home/jenkins/report
psql -d db -c "\$(sed 's/state_name/'"$state"'/' county.sql)" -U user
echo $state
EOF
done

How to use expect inside bash script [duplicate]

This question already has an answer here:
Embedding an Expect script inside a Bash script
(1 answer)
Closed 5 years ago.
Could anybody please tell me why this is not working?
#!/bin/bash
cd /home
touch somefile
/usr/bin/expect<<FILETRANSFER
spawn scp -r -P remoteServerPort somefile remoteServerIP:/home
expect "assword:"
send "MyPassWord\r"
interact
FILETRANSFER
echo "It's done"
It doesn't give any error but file is not transferred to remote server.I have tried many ways still couldn't find any solution.
The bash script you have defined is passing the expect commands on the standard input of expect. However, the expect command requires its arguments on a file or as an argument using the -c option.
You have several options but to add the less modifications on your script you just need to use the process substitution to create a here-document (temporary) for the expect command.
#!/bin/bash
echo "[DEBUG] INIT BASH"
cd /home
touch somefile
/usr/bin/expect <(cat << EOF
spawn scp -r -P remoteServerPort somefile remoteServerIP:/home
expect "Password:"
send "MyPassWord\r"
interact
EOF
)
echo "[DEBUG] END BASH"

expect sudo ssh login issue [duplicate]

This question already has answers here:
How can I escape a double quote inside double quotes?
(9 answers)
Closed 5 years ago.
i wrote an expect script to ssh remotely to multiple linux boxes and running this command chmod -R o-w /etc/
But i am getting an error expect: invalid option -- 'R'
Please find the script below
#!/bin/bash
username=$1
userpass=$2
rootpass=$3
cat server_list | while read host
do
expect -c "
set timeout 5
spawn ssh -o StrictHostKeyChecking=no -tq ${username}#${host} sudo su - root
expect "ssword" { send "${userpass}r" }
expect "ssword" { send "{rootpass}r" }
expect "#"
send "chmod -R o-w /etc"
expect "#" { send "exitr" }
expect eof"
done
i am running the script like this
./test1.sh test test#123 test#123
Kindly help
Use "--" flags in the send command which will force the next argument to be read as string.
send -- "chmod -R o-w /etc"
Read more in Expect manpage

How can I use sshpass with a blank password coming from a variable? [duplicate]

This question already has answers here:
When to wrap quotes around a shell variable?
(5 answers)
Closed 6 years ago.
I would like to write a script that can ssh into a linux target without any user interaction. The machine my script runs from as well as the targets that I'm trying to ssh into get reformatted every night so I can't use ssh-keygen (as far as I've seen) because I'm required to enter in the target's password manually when the keys are being set up. So instead I'm trying to use sshpass. Here's a simple example of how I'd like to use it:
#!/bin/bash
host=$1
user=$2
pass=$3
sshpass -p $pass scp myfiles.tar.gz $user#$host:/
sshpass -p $pass ssh $user#$host "tar xvf myfiles.tar.gz"
This works fine EXCEPT when the target's password is blank. If instead I write:
sshpass -p "" scp myfiles.tar.gz $user#$host:/
sshpass -p "" ssh $user#$host "tar xvf myfiles.tar.gz"
The commands work fine for that target. So I'd like to be able to do this somehow with the 'pass' variable that I was using. I've tried things like
pass=""
pass="\"\""
pass="''"
pass="\n"
but none of them seem to work. Does anyone know what I need to set my 'pass' variable to?
Always quote your variables:
...
pass=""
sshpass -p "$pass" scp myfiles.tar.gz "$user#$host:/"
sshpass -p "$pass" ssh "$user#$host" "tar xvf myfiles.tar.gz"
This prevents empty strings from disappearing, and also prevents other issues like passwords with spaces splitting up and passwords with asterisks turning into filenames.
PS: shellcheck automatically points this out.

sudo cat << EOF > File doesn't work, sudo su does [duplicate]

This question already has answers here:
How do I use sudo to redirect output to a location I don't have permission to write to? [closed]
(15 answers)
Closed 6 months ago.
I tried the following on the command prompt in bash:
sudo cat << EOF > /etc/yum.repos.d/some-name.repo
#Content
#....
#...
EOF
It complained :
-bash: /etc/yum.repos.d/some-name.repo: Permission denied
Then I did sudo su and tried the exact same thing except the sudo before cat, and it worked without any problem. What am I missing in the above ?
Output redirection (e.g., >) is performed by bash, not by cat, while running with your UID. To run with root's UID use sudo:
sudo bash -c 'cat << EOF > /etc/yum.repos.d/some-name.repo
line1
line2
line3
EOF'
Another option is tee.
cat << EOF | sudo tee -a /etc/yum.repos.d/some-name.repo
...
EOF
As a variation to #Yuriy Nazarov's answer, only the piped output needs to be elevated thru sudo. The piped input can stay un-elevated:
sudo bash -c 'cat > /etc/yum.repos.d/some-name.repo' << EOF
line1
line2
line3
EOF
This means a much smaller portion of the command needs to be quoted and sent thru to sudo.
As others have pointed out the shell redirection is done by the current shell not by cat. sudo only changes the permission of the program that is executed not of the shell doing the redirect. My solution to this is to avoid the redirect:
sudo dd of=/etc/yum.repos.d/some-name.repo << EOF
if you are using ' inside the text then you may use:
$ sudo bash -c "cat > /etc/postfix/mysql-virtual_forwardings.cf << EOF
user = mail_admin
password = password
dbname = mail
query = SELECT destination FROM forwardings WHERE source='%s'
hosts = 127.0.0.1
EOF
"
this is tested on google cloud's virtual server centos 7.0

Resources