ssh blocking when trying to store command output to variable - bash

I'm not quite sure what the issue is. I'm on Kali Linux 2.0 right now, fresh install. The following worked on Ubuntu 14.04 but it's not working anymore (maybe I accidentally changed it?). It looks correct to me, but every time it runs it blocks.
backup_folder=$(ssh -i /home/dexter/.ssh/id_rsa $server 'ls -t '$dir' | head -1')
This is part of a larger script. $server and $dir are set. When I run the command alone, I get the correct output, but it doesn't end the connection.

I don't know if this may help to solve the question but your command doesn't handle dirs with space in the filename. Add double quotes inside the single quote section like this:
SERVER='remoteServer' && REMOTE_DIR='remoteDir' && backup_folder=$(ssh -i /home/dexter/.ssh/id_rsa "${SERVER}" 'ls -t "'${REMOTE_DIR}'" | head -n1'); echo "${backup_folder}"
If it doesn't help try to add increasing number of -v switch to ssh to debug eventually reaching:
SERVER='remoteServer' && REMOTE_DIR='remoteDir' && backup_folder=$(ssh -vvv -i /home/dexter/.ssh/id_rsa "${SERVER}" 'ls -t "'${REMOTE_DIR}'" | head -n1'); echo "${backup_folder}"
If the verbose output does not help may be an MTU problem (these kind of problems are not of binary type, acts strangely).
You can try lowering MTU (usually 1500) on your side to solve:
sudo ifconfig eth0 mtu 1048 up
eth0 is obviously an example interface, use your own.

Related

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!! :)

Small script involving grep to pass on for the next command

My network card's name keeps alternating names between enp4s0 and enp3s0 after startup. In addition, it also starts DOWN. Everytime I login I have to do this, manually:
ip link # it outputs the names
sudo ip link set enpXs0 up
sudo dhcpcd
So I tried to make a small script to be run with .xinitrc. This is what I came up with:
#!/bin/bash
CARD=ip link | grep -o enp[4\|5]s0
echo ${CARD} # check
sudo ip link set ${CARD} up
sudo dhcpcd
but it doesn't work: link: missing operand. I thought I have to use quotes when assining CARD, it's not so. Neither is using full path names (/usr/bin/ip). How to set up the CARD variable?
#!/bin/bash
CARD=`ip link | grep -o enp[4\|5]s0` #here in card need save result
echo ${CARD} # check
sudo ip link set ${CARD} up
sudo dhcpcd
Command substitution.
Command substitution:
#!/bin/bash
CARD=$(ip link | grep -o enp[4\|5]s0) #here in card need save result
echo ${CARD} # check
sudo ip link set ${CARD} up
sudo dhcpcd
Backtick are not recommended while using command substitution.

Remote login (ssh differences)

I would like to know what is the difference between the below commands:
ssh vagrant#someipaddress
cd /home/vagrant/
grep -i "something" data.txt
and
ssh vagrant#someipaddress 'cd /home/vagrant; cat data.txt' | grep -i "something"
From this website it mentions, that you can send multiple commands to the remote server. Is the second option actually logging into the server? What is the benefit in this second approach?
Strictly Speaking from the example provided:
The first command:
Logs onto the remote server
Executes a couple commands, and
Stays logged on to the server
The second command runs half on the remote machine, logs out of the remote machine, and then pipes the output to grep on your local machine, all in one command line.
Breaking down what's happening:
ssh vagrant#someipaddress 'cd /home/vagrant; cat data.txt' | grep -i "something"
The section in bold is running on your local PC, based on the output from the ssh session
The 'quotes "contain" the entire command block
the " quotes "contain" the individual arguments within the command block.
You may have meant to do this:
ssh vagrant#someipaddress 'cd /home/vagrant; cat data.txt' | grep -i "something"
Where the bold section runs locally
Or you may have intentionally done this:
ssh vagrant#someipaddress 'cd /home/vagrant/ | grep -i "something" data.txt'
Where the entire command runs on the server.
Either way, the end result:
Is that you automatically log out of the remote machine, and the whole command sequence was executed in one hit.

ChromeOS init problems

Currently having issues when attempting to run a MAC changing script on startup.
Currently running ChromeOS which is using upstart as it's init system however I've attempted multiple different ways to make the script run at boot with no luck.
Running the script alone via sudo sh updatemac.sh has it working correctly, code here:
#!/bin/bash
NEW_MAC=`echo -n 00; hexdump -n 5 -v -e '/1 ":%02X"' /dev/urandom;`
ifconfig wlan0 down
ifconfig wlan0 hw ether $NEW_MAC
ifconfig wlan0 up
I've attempted to create a startup job a few different ways.
First way was placing updatemac.conf in /etc/init with the code:
start on star-user-session
task
script
NEW_MAC=`echo -n 00; hexdump -n 5 -v -e '/1 ":%02X"' /dev/urandom;`
ifconfig wlan0 down
ifconfig wlan0 hw ether $NEW_MAC
ifconfig wlan0 up
end script
However that didn't work. I also tried replacing the script / end script section with both
exec /home/user/chronos/Downloads/updatemac.sh
And
exec sh /home/user/chronos/Downloads/updatemac.sh
Neither of which worked.
The other way I tried was adding the script directly to /etc/init.d/updatemac.sh
However that also failed for me.
Solved it, seems it needed
start on started system-services
In the .conf for /etc/init instead of
start on star-user-session
Also removed "task" from the script.

ssh login without welcome banner

I am using ssh from a program which sends commands to ssh and parses answers. However, each time I log in, I get the welcome banner like:
Linux mymachine 3.2.0-4-686-pae #1 SMP Debian 3.2.54-2 i686
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
...
I do not want this banner, because my parser would need to deal with it. Is it possible to login with ssh and not to get this banner at the beginning?
You should be able to silence this banner, and other diagnostic messages, by passing -q to SSH:
ssh -q user#remote_host
If you want to make -q permanent for all your SSH sessions, do:
echo "LogLevel QUIET" >> ~/.ssh/config
What works here seems to depend on the operating system, SSH version, and the server-side configuration of sshd.
For connecting to a stock Ubuntu 18 server ssh -q didn't work for me, and neither did ssh -o LogLevel=error that is suggested elsewhere.
What did work is the comment posted under the question about creating a .hushlogin file in the remote user's home directory:
$ ssh myuser#myhost
Welcome to Ubuntu 18.04.2 LTS (GNU/Linux 4.15.0-55-generic x86_64)
<snip>
Last login: Thu Aug 1 14:04:26 2019 from 1.2.3.4
myuser#myhost$ touch .hushlogin
myuser#myhost$ exit
Then:
$ ssh myuser#myhost echo 'Test'
Test
This will run command1 command2 and command3 on the remote_host.
ssh user#remote_host 'command1; command2; command3'
No banners are displayed.
Try ssh -q to supress the banner message
If you expect more than 1000 lines in the server answer then replace 1000 with a corresponding number or the server answer will be truncated.
# Demo script file creation \
DIVIDER="___"; echo "echo $DIVIDER; echo 100; echo 200; echo 300;" > "./test.sh"; \
# \
# Getting the answer without the banner \
ssh -q login#server.name < "./test.sh" | grep -A1000 -e "^$DIVIDER" | tail -n +2
Success
100
200
300
The same command without
| grep -A1000 -e "^$DIVIDER" | tail -n +2
gives
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux...
[...]
Run 'do-release-upgrade' to upgrade to it.
___
100
200
300
You can replace "___" (three underscores) with any exotic sign(s) or even password (which can't be found in the beginnings of lines of the banner).
To avoid the replacing 1000 with a corresponding number (and possible truncation of big server answers) search something about "how to grep all lines after match" and modify my code.
For running commands remotely:
#!/bin/bash
SCRIPT='
#Your commands
'
sshpass -p<pass> ssh -o 'StrictHostKeyChecking no' -p <port> user#host "$SCRIPT"
I answer my own question with the solution based on Keith Reynolds answer. I am using:
ssh my_host bash
allowing bash interaction without banner and without prompt.

Resources