OpenWRT ASH script - bash

I am trying to write an ASH script to run on my OpenWRT router.
I have installed onto it nodogsplash, which displays a login page when you first try to authenticate with the router.
nodogsplash comes with a command line utility which allows you to change the password:
ndsctl password newpassword
So I am trying to write a script which I can setup as a cron job to run once a day to change the password to something new, however I am struggling to get it to output correctly. My script atm:
#!/bin/ash
local randompassLength
local pass
randompassLength=8
pass=</dev/urandom tr -dc A-Za-z0-9 | head -c $randompassLength
ndsctl password "$pass"
When I run this I get the output:
miqM2Ah6Password set to .
Which seems to chuck the password at the start of the echo and set the password to blank.
Any ideas what I am doing wrong here?

You're missing command substitution:
pass=$(</dev/urandom tr -dc A-Za-z0-9 | head -c $randompassLength)
or using backquotes:
pass=`</dev/urandom tr -dc A-Za-z0-9 | head -c $randompassLength`

Related

script to connect to a "list.txt" of servers

I am trying to find a way to connect to a list of servers written in a simple textfile to run one command and write the output to a file...
The small problem is, I have to login with a password... but it would not a problem to paste the password into the script.
the full command would be:
ssh "server_from_list.txt uptime | awk -F, '{sub(".*up ",x,$1);print $1}' >> /home/kauk2/uptime.out
lets assume the password is: abcd1234
Any suggestions??? I am not fit in scripting, sorry...
Many thanks to you all in advance...
regards,
Joerg
Ideally you should set up password-less login, but failing that you can use sshpass. First, get a single command working by trying the following:
export SSHPASS=abcd1234
Then you can try:
sshpass -e ssh user#server1 'uname -a'
When you get that debugged and working, you can use GNU Parallel to run the command on all servers in a file called list.txt
user#server1
user#server2
user#server3
user#server4
The command will be:
parallel -k -a list.txt sshpass -e ssh {} 'uptime'

How to ssh to a server and get CPU and memory details?

I am writing a shell script where i want to ssh to a server and get the cpu and memory details data of that displayed as a result. I’m using the help of top command here.
Script line:
ssh -q user#host -n “cd; top -n 1 | egrep ‘Cpu|Mem|Swap’”
But the result is
TERM environment variable is not set.
I had checked the same in the server by entering set | grep TERM and got result as TERM=xterm
Please someone help me on this. Many thanks.
Try using the top -b flag:
ssh -q user#host -n "cd; top -bn 1 | egrep 'Cpu|Mem|Swap'"
This tells top to run non-interactively, and is intended for this sort of use.
top need an environment. You have to add the parameter -t to get the result:
ssh -t user#host -n "top -n 1 | egrep 'Cpu|Mem|Swap'"
Got it..!! Need to make a small modification for the below script line.
ssh -t user#host -n "top -n 1 | egrep 'Cpu|Mem|Swap'"
Instead of -t we need to give -tt. It worked for me.
To execute command top after ssh’ing. It requires a tty to run. Using -tt it will enable a force pseudo-tty allocation.
Thanks stony for providing me a close enough answer!! :)

SSH to server, Sudo su - then run commands in bash [duplicate]

This question already has answers here:
Pass commands as input to another command (su, ssh, sh, etc)
(3 answers)
Closed 6 years ago.
I have the following
#!/bin/bash
USER='scott'
PASS='tiger'
ssh -t $USER#server006.web.com "sudo su - http"
This Works, but I was trying to get it to run a script afterwards, and if I do, using -c or <
The script does a grep like this:
grep -i "Exception:" /opt/local/server/logs/exceptions.log | grep -e "|*-*-*:*:*,*|" | tail -1 | awk -F'|' '{print $2}' >> log.log
This also works fine on it's own, but I need to be http to do it.
I cannot SCP the output of the script back to server001 either, so I'm stuck here,
Any ideas would be relay appreciated.
Ben
Try
ssh -t $USER#server006.web.com 'sudo -u http grep -i "Exception:" /opt/local/server/logs/exceptions.log | grep -e "|*-*-*:*:*,*|" | tail -1 | awk -F"|" "{print $2}" >> log.log'
Sudo already runs the command as a different user to there's no need to su again.
Only reason to do sudo su is to have a fast way to start a new shell with another user.
You probably want sudo -u instead of sudo su -:
ssh -t $USER#server006.web.com sudo -u http script
Guess I'm late to the party.
My solution:
ssh -t $USER#server006.web.com "sudo cat /etc/shadow"
and replace cat /etc/shadow with your desired program.

bash: while read loop - stop if there is variable sshpass

i have a problem with my bash script. I read line by line the variable lvm_path_exec, that works. I confirmed it with echo "lvmpath".
But as soon as i place a sshpass command into the while statement the script only process the first line which got grepped.
If there is no sshpass command all lines of lvmpath_exec get processed.
Do you see the error?
lvmpath_exec=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} lvdisplay | grep datatest -A 3 | grep Path | awk '{ print $3 }')
echo "$lvmpath_exec" | while read lvmpath
do
lvmname=datatest
snap=_snapshot
snapname=$lvmname$snap
lvcreate=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} lvcreate -L20G -s -n $snapname $lvmpath)
snap_path=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} lvdisplay | grep $snapname -A 3 | grep Path | awk '{ print $3 }')
transfer=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} "dd if=$snap_path | gzip -c" > /tmp/$snapname)
delsnap=$(sshpass -p "${password[$i]}" ssh ${user[$i]}#${ip[$i]} -p ${port[$i]} lvremove -f $snap_path)
done
UPDATE
I fixed it:
replace
echo "$lvmpath_exec" | while read lvmpath
with
for lvmpath in $lvmpath_exec
But shouldnt it work with while read too?
sshpass works by manipulating stdin to fool ssh into thinking it is getting the password from an interactive user. When you use a ... | while style loop, the loop iterates for every line coming from stdin, which sshpass wipes out after the first call, that's why only the first line gets executed. The for loop doesn't use stdin, that's why it doesn't have this problem.
As man sshpass explains, this tool is inherently insecure and you should really be using public key authentication instead. Also keep in mind that it has other ways of passing the password, using the -p flag is the least safe method of all, and any other method would be safer, for example the -e flag seems trivially easy. I know you might insist you have a legitimate use case, but this is so important I'm just gonna quote from the man page:
First and foremost, users of sshpass should realize that ssh's insis‐
tance on only getting the password interactively is not without reason.
It is close to impossible to securely store the password, and users of
sshpass should consider whether ssh's public key authentication pro‐
vides the same end-user experience, while involving less hassle and
being more secure.
The -p option should be considered the least secure of all of sshpass's
options. All system users can see the password in the command line
with a simple "ps" command. Sshpass makes a minimal attempt to hide the
password, but such attempts are doomed to create race conditions with‐
out actually solving the problem. Users of sshpass are encouraged to
use one of the other password passing techniques, which are all more
secure.
have you tried this..have not tried though
export SSHPASS=password[$i]
sshpass -e ssh -oBatchMode=no user[$i]#{ip[$i]} ..

Shell script to run a command and send the commands output as a report in email

I am trying to write a shell script which will run a command to ssh into multiple machines and store the output in a variable and send it as a report via email.Here is what I have in the script as of now:
#!/bin/bash
DcEmitterConn='yinst ssh -H test.out "netstat -a | grep ES | grep 25019 | wc"'
SUBJECT="DC-Connections"
EMAIL="abc#abc.com"
EMAILMESSAGE="report.out"
echo $DcEmitterConn> $EMAILMESSAGE
#send email using /bin/mail
/bin/mail -s "$SUBJECT" "$EMAIL"< $EMAILMESSAGE
After executing the above command in the script it would ask me for a password and then would print the requested output. The problem i am facing in the above script is that I am not able to store the command output in the variable and print it in the email body. Can someone please let me know if I am missing something.
the output would look something like this:
abc#dh1.data.ac2.abc.com's password: (yinst-pw)
40 240 3560
abc#dh2.data.ac2.abc.com's password: (supplied by yinst-pw)
50 300 4450
Thanks in advance!
You should put double quotes around $DcEmitterConn on line 8. And you can avoid the temporary file:
SUBJECT="DC-Connections"
EMAIL="abc#abc.com"
yinst ssh -H test.out "netstat -a | grep ES | grep 25019 | wc" | /bin/mail -s "$SUBJECT" "$EMAIL"

Resources