Adding logfile command puts script on the loop? - linux

I'm trying to create logfile for output/terminal files of a script.
Why is script going for the loop?
Script is used for remotely changing passwords over ssh using imported .txt file with list of addresses. Script is working fine until I add line for logging at the end after DONE:
#!/bin/bash
echo "Enter the username for which you want to change the password"
read USER
sleep 2
echo "Enter the password that you would like to set for $USER"
read PASSWORD
sleep 2
echo "Enter the file name that contains a list of servers. Ex: ip.txt"
read FILE
sleep 2
for HOST in $(cat $FILE)
do
ssh root#$HOST "echo $'$PASSWORD\n$PASSWORD' | passwd $USER"
done
I tried adding following log creating commands:
/root/passwordchange.sh | tee -a /root/output.log
logsave -a /root/output.log /root/passwordchange.sh
/root/passwordchange.sh >> /root/output.log
Adding logging line is creating loop for entire program instead of closing it.
I need to sigkill script to end the process.
Output file is created just as normal with all the information provided.
It is my first question here on stack, thank you from advance for all answers

Related

How to have a script trigger in my script after it ssh's into a DC's Time clock server?

So, I have a script which it's intended purpose is to:
Ask for the DC number and Time clock number
log in to the Time clock server for the DC stated above
After log in, it is intended to run a seperate script inside my script which updates the time clock number also stated above.
My issue is that once I trigger the script, it logs into the server as intended, prompts me for my user ID, and then I have to press "enter" when "xterm" comes up after that. After this, the update script is supposed to run, however, it doesn't, and sits at the command line.
After I exit the server, THEN it runs the update script, but fails, because the update script doesn't exist in the jump box.
My question is, after the script logs in to the server, how can I get it to trigger the script inside the Time clock server, as I am wanting it to? Thanks.
Script is below:
#!/bin/bash -x
export LANG="C"
####
####
## This script is intended to speed up the process to setup timeclocks from DC tickets
## Created by Blake Smreker | b0s00dg | bsmreker#walmart.com
####
####
#Asks for DC number
echo "What is the four digit DC number?"
read DC #User input
#Asks for Timeclock number
echo "What is the two digit Timeclock number?"
read TMC #User input
#Defines naming convention of tna server
tnaserver="cs-tna.s0${DC}.us.wal-mart.com"
#creating variable to define the update script
tcupd="/u/applic/tna/shell/tc_software_update.sh tmc${TMC}.s0${DC}.us REFURBISHED"
#Logging in to the cs-tna package at the specified DC
/usr/bin/dzdo -u osedc /bin/ssh -qo PreferredAuthentications=publickey root#$tnaserver
echo "Preforming Timeclock update on Timeclock=$TMC, at DC=${DC}"
echo ""
echo "-----------------------------------------------------------------------------------------------------------------------------------------"
$tcupd #Runs update script
echo "-----------------------------------------------------------------------------------------------------------------------------------------"
echo ""
sleep 2
echo "If prompted to engage NOC due to Timeclock not being on the network, send the ticket to DC Networking"
echo ""
echo "OR"
echo ""
echo "If the script completed successfully, and the Timeclock was updated, you can now resolve the ticket"
You must run the command inside ssh session, not after it:
echo "Preforming Timeclock update on Timeclock=$TMC, at DC=${DC}"
echo ""
echo "-----------------------------------------------------------------------------------------------------------------------------------------"
###### $tcupd #Runs update script
/usr/bin/dzdo -u osedc /bin/ssh -qo PreferredAuthentications=publickey root#$tnaserver /bin/bash -c /u/applic/tna/shell/tc_software_update.sh tmc${TMC}.s0${DC}.us REFURBISHED
echo "-----------------------------------------------------------------------------------------------------------------------------------------"
echo ""
sleep 2
echo "If prompted to engage NOC due to Timeclock not being on the network, send the ticket to DC Networking"
echo ""
echo "OR"
echo ""
echo "If the script completed successfully, and the Timeclock was updated, you can now resolve the ticket"
From man ssh you see ssh [-46AaCfGgKkMNnqsTtVvXxYy] ....... destination [command]. If [command] is not given ssh runs remote login command scripts, for example xterm. You read more here or here or just browse google.
You need to think how and which environment variable you want to pass to the remote machine and remember about properly enclosing the variables, so they get expanded on your or the remote machine.

Execute Bash script remotely via cURL

I have a simple Bash script that takes in inputs and prints a few lines out with that inputs
fortinetTest.sh
read -p "Enter SSC IP: $ip " ip && ip=${ip:-1.1.1.1}
printf "\n"
#check IP validation
if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "SSC IP: $ip"
printf "\n"
else
echo "Enter a valid SSC IP address. Ex. 1.1.1.1"
exit
fi
I tried to upload them into my server, then try to run it via curl
I am not sure why the input prompt never kick in when I use cURL/wget.
Am I missing anything?
With the curl ... | bash form, bash's stdin is reading the script, so stdin is not available for the read command.
Try using a Process Substitution to invoke the remote script like a local file:
bash <( curl -s ... )
Your issue can be simply be reproduced by run the script like below
$ cat test.sh | bash
Enter a valid SSC IP address. Ex. 1.1.1.1
This is because the bash you launch with a pipe is not getting a TTY, when you do a read -p it is read from stdin which is content of the test.sh in this case. So the issue is not with curl. The issue is not reading from the tty
So the fix is to make sure you ready it from tty
read < /dev/tty -p "Enter SSC IP: $ip " ip && ip=${ip:-1.1.1.1}
printf "\n"
#check IP validation
if [[ $ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "SSC IP: $ip"
printf "\n"
else
echo "Enter a valid SSC IP address. Ex. 1.1.1.1"
exit
fi
Once you do that even curl will start working
vagrant#vagrant:/var/www/html$ curl -s localhost/test.sh | bash
Enter SSC IP: 2.2.2.2
SSC IP: 2.2.2.2
I personally prefer source <(curl -s localhost/test.sh) option. While it is similar to bash ..., the one significant difference is how processes handled.
bash will result in a new process being spun up, and that process will evoke commands from the script.
source on the other hand will use current process to evoke commands from the script.
In some cases that can play a key role. I admit that is not very often though.
To demonstrate do the following:
### Open Two Terminals
# In the first terminal run:
echo "sleep 5" > ./myTest.sh
bash ./myTest.sh
# Switch to the second terminal and run:
ps -efjh
## Repeat the same with _source_ command
# In the first terminal run:
source ./myTest.sh
# Switch to the second terminal and run:
ps -efjh
Results should look similar to this:
Before execution:
Running bash (main + two subprocesses):
Running source (main + one subprocess):
UPDATE:
Difference in use variable usage by bash and source:
source command will use your current environment. Meaning that upon execution all changes and variable declarations, made by the script, will be available in your prompt.
bash on the other hand will be running in as a different process; therefore, all variables will be discarded when process exits.
I think everyone will agree that there are benefits and drawbacks to each method. You just have to decide which one is better for your use case.
## Test for variables declared by the script:
echo "test_var3='Some Other Value'" > ./myTest3.sh
bash ./myTest3.sh
echo $test_var3
source ./myTest3.sh
echo $test_var3
## Test for usability of current environment variables:
test_var="Some Value" # Setting a variable
echo "echo $test_var" > myTest2.sh # Creating a test script
chmod +x ./myTest2.sh # Adding execute permission
## Executing:
. myTest2.sh
bash ./myTest2.sh
source ./myTest2.sh
./myTest2.sh
## All of the above results should print the variable.
I hope this helps.

Executed Bashscript alters command

Im using Bashscript for automated backups from my system and most important config files.
Strange thing is, after running the script it should send me an email with content of a log file. But debugging the script reveals, that it runs an altered command than written in my script
Script:
#!/bin/bash
###########################
### ###
### BACKUP SCRIPT ###
### ###
###########################
......
LOG="backup.log"
exec > >(tee -i >( sed 's/\x1B\[[0-9;]*[JKmsu]//g' > ${LOG}))
exec 2>&1
# commands etc
mailx -s "Backup | subject" mail#mail.tld < $LOG
So my log contains all necessary output and isn't empty.
Debugging the script reveals this
echo -e '\033[1;32mExiting prune script\033[0m'
Exiting prune script
+ mailx -s 'Backup | subject' mail#mail.tld #Missing < $LOG!!!
Really dunno why it's missing my logfile. The mail I receive ist just an empty mail with correct subject.
Some ideas why?
PS: using Ubuntu 16.04 LTS but this shouldn't matter
Backup.log: https://pastebin.com/cCVSLV0h nothing special.
If I run mail command directly from my shell it sends this log as I expect it.

Read command in bash script not waiting for user input when piped to bash?

Here is what I'm entering in Terminal:
curl --silent https://raw.githubusercontent.com/githubUser/repoName/master/installer.sh | bash
The WordPress installing bash script contains a "read password" command that is supposed to wait for users to input their MySQL password. But, for some reason, that doesn't happen when I run it with the "curl githubURL | bash" command. When I download the script via wget and run it via "sh installer.sh", it works fine.
What could be the cause of this? Any help is appreciated!
If you want to run a script on a remote server without saving it locally, you can try this.
#!/bin/bash
RunThis=$(lynx -dump http://127.0.0.1/example.sh)
if [ $? = 0 ] ; then
bash -c "$RunThis"
else
echo "There was a problem downloading the script"
exit 1
fi
In order to test it, I wrote an example.sh:
#!/bin/bash
# File /var/www/example.sh
echo "Example read:"
read line
echo "You typed: $line"
When I run Script.sh, the output looks like this.
$ ./Script.sh
Example read:
Hello World!
You typed: Hello World!
Unless you absolutely trust the remote scripts, I would avoid doing this without examining it before executing.
It wouldn't stop for read:
As when you are piping in a way you are forking a child which has been given input from parent shell.
You cannot give the values back to parent(modify parent's env) from child.
and through out this process you are always in parent process.

Executing two command at remote server and storing the output to local server using shell scripting

I'm trying to clean up my shell script. I am trying to read the list of server for
a text file "serverlist" and shh each server to get the outcome of the command and store in to a file "result_segfault". I managed to do that however for each server i wanted to list the name of the server and the output below:
Example :
-----------------
Servername
-----------------
Output of the command
----------------
Servername2
------------------
Output of the command
This is my code
#!/bin/bash
for HOSTNAME in $(cat serverlist);
do
SCRIPT="cat /var/log/messages | grep 'segfault at 0000000000000098'"
for HOSTNAME in ${HOSTNAME} ;
do
ssh ${HOSTNAME} "${SCRIPT}" >"result_segfault"
done;
done
I didn't know how to add the Server name and the separator
{
echo "----------------"
echo "$HOSTNAME"
echo "----------------"
ssh "$HOSTNAME" "${SCRIPT}"
} >>"result_segfault"
The braces {...} group statements together so that their stdout can be collected with a single redirect. I used ">>" in place of ">" for the redirect because it appeared from your sample that you wanted to append together the results from each host rather than overwrite it each time a new host is queried.
With various stylistic fixes;
#!/bin/bash
while read HOSTNAME
do
ssh ${HOSTNAME} grep 'segfault at 0000000000000098' /var/log/messages
done <serverlist >result_segfault

Resources