Feed expect with some variables - bash

I would like to use expect with cryptsetup. It could be whatever program instead of cryptsetup. I feed cryptsetup with a device, a virtual device name and a password.
#!/bin/bash
read -p "Device: `echo $'\n> '`" DEV
read -p "Virtual Device: `echo $'\n> '`" VIRTUAL
read -p "Password: `echo $'\n> '`" PSWD
expect -c exec /sbin/cryptsetup luksOpen /dev/$DEV $VIRTUAL
expect "Enter passphrase for /dev/sdc1:"
send $PSWD
I also tried with 'spawn' but it does not work either.
any idea is more than welcome! thanx folks.

You can overcome the expect dependency by substituting the last three lines of codes with the following :
echo $PSWD | cryptsetup luksOpen /dev/$DEV $VIRTUAL

As I understand you question and comments, you need something like this:
#!/bin/bash
read -p "Device: `echo $'\n> '`" DEV
read -p "Virtual Device: `echo $'\n> '`" VIRTUAL
/sbin/cryptsetup luksOpen /dev/$DEV $VIRTUAL
mount /dev/mapper/$VIRTUAL /mnt/$DEV
cryptsetup will ask you password, you will enter it. After this mount will run. That's all. And you don't need expect and any variable to store password.

Related

How to pass password to sudo from environment variable without prompt appearing?

How do I pass my password to sudo from an environment variable through stdin without the sudo prompt appearing?
I have tried $ echo $PASSWORD | sudo -S echo foo but that returns [sudo] password for mithic: foo.
Using the -n flag just always returns sudo: a password is required (unless I have recently inputted the correct password).
You can set an empty password prompt:
printf '%s\n' "$PASSWORD" | sudo -p "" -S echo foo
If it's really in the environment, I would recommend using the -A option instead of -S. Write a very small script that writes the value to standard output.
#!/bin/sh
printf '%s' "$PASSWORD"
Call it something like asker and make it executable
chmod +x asker
The do the following:
SUDO_ASKPASS=./asker sudo -A echo foo
-A makes sudo run the executable named by SUDO_ASKPASS and read the password from its output.

tee not working with ssh running an external script

I'm trying to log everything happening during an ssh session while showing output on shell.
sshpass -p "password" ssh -tt -o ConnectTimeout=10 -oStrictHostKeyChecking=no username#"$terminal" 'bash -s' < libs/debug-mon.lib "$function" | grep -E '^INFO:|^WARNING:' || echo "WARNING: Terminal not reacheable or wrong IP" | tee -a libs/debug-monitor-logs
I'm not getting anything on the log libs/debug-monitor-logs file
Could you please help me to see where the issue is?
Thanks
looks like this only thing you will ever write into the log file is "WARNING: Terminal not reacheable or wrong IP"
try something like this
(command-that-might-fail || echo error message) | tee -a log-file
instead of
commant-that-might-fail || echo error message | tee -a log-file
(put the whole expression in brackets that you want to pipe into tee)

Waiting for input from script that is running remotely via ssh

There is a script I'm running that I can not install on the remote machine.
clear && printf '\e[3J'
read -p "Please enter device: " pattern
read -p "Enter date: (YYYY-MM-DD): " date
pfix=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 5 | head -n 1)
mkdir /home/user/logCollectRes/"${pfix}"
ssh xxx.xxx.xxx.xxx 'bash -s' < /usr/local/bin/SearchAdvanced.sh ${pattern} ${date} ${pfix}
In that script, I would like to be able to use read.
ls -g *"${pattern}"*
read -p "Select one of these? [y/n] " "found";
I've tried adding the -n on the read as well as the -t -t option on ssh. As you can see the script presents information that is only seen once the script starts, so I can't use the read on local machine.
EDIT: So lets say server B stores syslogs for 5K computers. The file names are given by using the internal IP of the device and the date at the end.
/var/log/remotes/192.168.1.500201505050736.gz
/var/log/remotes/192.168.1.500201505050936.gz
/var/log/remotes/192.168.1.500201505051136.gz
/var/log/remotes/192.168.1.600201505050836.gz
/var/log/remotes/192.168.1.600201505051036.gz
/var/log/remotes/192.168.1.600201505051236.gz
I'd like to be able to select the IP address from the main script, list all the files matching that IP address, and then select which I want to scp to my local machine.
After speaking with some coworkers I found the answer to be running two scripts: The first pulls the ls -g result and directs the answer to a variable on the local machine. I then print that output with the read option of selecting on of the files. The 2nd script will take that answer and scp the file from the remote machine
In the main script
ssh xxx.xxx.xxx.xxx 'bash -s' < /usr/local/bin/SearchAdvanced.sh ${pattern} ${date} > ${result}
then as a follow up
printf "${result}"
read -p "Select file: "

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]} ..

How to connect to wifi in bash?

I'd like to make a simple bash script to connect to known wifi networks.
Thus far I have...
#!/bin/bash
NETWORK_ID=${1:myintranet}
WIRELESS_KEY=${2:""}
WIRELESS_DEVICE=${3:wlan0}
if [ ! -n "$WIRELESS_KEY" ]; then
read -s -p "Enter Password: " WIRELESS_KEY
fi
#ifconfig wlan0
iwconfig wlan0 essid $NETWORK_ID key s:$WIRELESS_KEY
dhclient wlan0
I enter the plain text password for the network when requested and it fails with the error
iwconfig: unknown command "s:myPassword"
But I can't find any reason why it should be expecting a command and not translating the key to hex.
This is working fine for me for WEP wifi. Don't forget to name the script with .sh extension.
#!/bin/bash
NETWORK_ID=${1:myintranet}
WIRELESS_KEY=${2:xxx}
WIRELESS_DEVICE=${3:wlan0}
if [ -z "$WIRELESS_KEY" ]; then
read -s -p "Enter Password: " WIRELESS_KEY
fi
#ifconfig wlan0
iwconfig wlan0 essid $NETWORK_ID key s:$WIRELESS_KEY
dhclient wlan0
For WPA wifi, it may not work. Consider using wpa_supplicant or configure it using wicd (wicd-gtk)

Resources