how to parse list of values to a command using a for sentence? - for-loop

my question is do you have any idea how to parse a list of arguments as a variable in for statement
iscsiadm -m discovery -t st -p 192.168.1.11 | awk -F ":" 'NF{print $NF}' | awk 'NR==1{print $1}'
vbox
vbox2
vbox3
vbox4
vbox5
vbox6
i want to pass a single parameter (vbox, vbox2,vbox3...) to a iscsi command to discover and login to this truenas vm
iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:vbox -p 192.168.1.11 -l
iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:vbox2 -p 192.168.1.11 -l

u mean like this ?
echo 'vbox vbox2 vbox3 vbox4 vbox5 vbox6' |
mawk 'sub(".+","iscsiadm -m node -T iqn.2005-10.org.freenas." \
"ctl:& -p 192.168.1.11 -l")^_' ORS=' ' RS='[[:space:]]+'
iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:vbox -p 192.168.1.11 -l iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:vbox2 -p 192.168.1.11 -l iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:vbox3 -p 192.168.1.11 -l iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:vbox4 -p 192.168.1.11 -l iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:vbox5 -p 192.168.1.11 -l iscsiadm -m node -T iqn.2005-10.org.freenas.ctl:vbox6 -p 192.168.1.11 -l

thanks RARE Kpop Manifesto !!!
also i have this one
printf '%s\n' "${nas[#]}" |paste -sd ' '
for nas in $vbox; do
discover=iscsiadm -m node -T $connector:$nas -p $ip -l
done

Related

Subscribe and Publish in BASH like a receive Buffer

I want to buffer all messages of a subscription during processing publish messages.
The reason is a firmware update over MQTT. I want to send data with crc and the microcontroller have to verify the content and need to answer with new address pointer.
For now, i got it working without any interaction from the microcontroller. If size doesn't fit, or mc is not online, my bash script sends all the data of the binary file into the nirvana.
If I publish a message and subscribe directly after the publish, it is possible to lose an answer very easily.
But I'm not so experienced with bash and I need some suggestions how to do this...
This is what I have:
mosquitto_pub -h $MQTT_SERVER -t "spiffs/${client_name}/file_info" -m "$binary_file" -p 8883 -i "fw_server" --cafile server-cert.pem -d --insecure -u $MQTT_USER -P $MQTT_PW
mosquitto_sub -h $MQTT_SERVER -p 8883 -t "+/${client_name}/#" -i "fw_server" --cafile server-cert.pem -d --insecure -u $MQTT_USER -P $MQTT_PW | while read -r payload
do
fp_jq_rspCode=".upload.fp" # file pointer
address=$(echo $payload | jq -r $fp_jq_rspCode)
echo "${payload}" | jq -c '.[]'
echo "address pointer:$address"
c=${address}
addr=$(printf '%08x' "$c")
content=$(xxd -p -c $payload_size -l $payload_size -seek $c $binary_file)
length=`expr length "$content"`
len=$(printf '%04x' "$length")
crc32=$(echo -n "$content" | gzip -c | tail -c8 | hexdump -n4 -e '"%u"')
crc32=$(printf '%08x' "$crc32")
echo "$addr $len $content $crc32"
message=$(printf '%08x%04x%s%s' "$c" "$length" "$content" "$crc32")
mosq=$(mosquitto_pub -h $MQTT_SERVER -t "spiffs/${client_name}/upload" -m "$message" -p 8883 -i "fw_server" --cafile server-cert.pem -d --insecure -u $MQTT_USER -P $MQTT_PW)
done

running a for loop over ssh remotely

team, I have below cord that does ssh login and stays connected. I want to run some commands in for loop but getting some syntax errors. The same exact commands work when i manually login to node and sudo bash and just copy paste.
code
read -p "specify just the list of nodes " nodes
for node in $nodes
do
ssh -q -F $HOME/.ssh/ssh_config -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -t $node.team.net \
"for line in `docker ps | grep test | awk '{print $1}'`;
do
POD_ID=$(docker inspect $line --format='{{ index .Config.Labels "io.kubernetes.pod.uid" }}')
POD_NAME=$(docker inspect $line --format='{{ index .Config.Labels "io.kubernetes.pod.name"}}')
POD_VOL="/var/lib/kubelet/pods/$POD_ID/volumes"
POD_DU=$(du -sh $POD_VOL < /dev/null)
HOSTNAME=$(hostname)
AGENT_SHA=$(docker inspect $line --format='{{ index .Config.Image }}' | cut -d ':' -f2)
STARTED_AT=$(docker inspect $line --format='{{ .State.StartedAt }}')
echo $HOSTNAME, $POD_NAME, $POD_DU, $AGENT_SHA, $STARTED_AT
done"
printf "\n"
done;
output
Your new SSH certificate is ready for use!
specify just the list of nodes node1
"docker inspect" requires at least 1 argument.
See 'docker inspect --help'.
Usage: docker inspect [OPTIONS] NAME|ID [NAME|ID...]
Return low-level information on Docker objects
"docker inspect" requires at least 1 argument.
See 'docker inspect --help'.
expected
container1 45GB
..
..
Is better send a file with script content and run. Something like:
Copy script
for a in {server1,server2,serverN};
do
scp your_script.sh root#$a:/path/to/your_script.sh
done
Exec script
for a in {server1,server2,serverN};
do
ssh root#$a "sh /path/to/your_script.sh par1 par2 parn";
done

How to close SSH socket

I'm working on enabling Session Multiplexing between two servers.
I want to close all existing sockets for this server(or IP) before creating new one and close newly created one after finishing my task. This is what I've done so far:
remote_ip=192.168.20.2 #User inut
remote_port=222
Can create socket by:
SSHSOCKET=~/.ssh/remote_$remote_ip
ssh -M -f -N -o ControlPath=$SSHSOCKET $remote_ip -p $remote_port
Can search control path by:
ps x | grep $remote_ip | grep ssh | cut -d '=' -f 2
/root/.ssh/remote_192.168.20.2 192.168.20.2 -p 222
Can close socket by:
ssh -S /root/.ssh/remote_192.168.20.2 192.168.20.2 -p 64555 -O exit
Trying to close the socket by:
ps x | grep $remote_ip | grep ssh | cut -d '=' -f 2 | xargs ssh -S | xargs -i {} "-O exit"
But I get:
Pseudo-terminal will not be allocated because stdin is not a terminal.
Tried using -t and -tt:
ps x | grep $remote_ip | grep ssh | cut -d '=' -f 2 | xargs ssh -Stt | xargs -i {} "-O exit"
ssh: Could not resolve hostname /root/.ssh/remote_192.168.20.2: Name or service not known
xargs: ssh: exited with status 255; aborting
Can anyone please help me with this?
If you want to kill every connection from your machine to a given remote IP address and port, you can do so as follows (using fuser, a tool from the psmisc package included with all major Linux distros):
fuser -k -n tcp ",${remote_ip},${remote_port}"

Generating bash script arrays with elements containing spaces from commands

I have a script that logs in to a remote host to pull a directory listing to later present options to the user. It was all working perfectly, until some of the directories started having spaces in them. I have tried several syntaxes and googled the life out of this and I am now at the end of my tether. The original command was this:
SERVERDIRS=($(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER#$SERVER ls -l --time-style="long-iso" $FROMFOLDER | egrep '^d' | awk '{print $8}'))
I first off changed this code to be able to read the spaces like this:
SERVERDIRS=($(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER#$SERVER ls -l --time-style="long-iso" $FROMFOLDER | egrep '^d' | cut -d' ' -f8-))
However This resulted in each word being recognised as a variable. I have tried many ways to try to solve this, two of which were:
SERVERDIRS=($(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER#$SERVER ls -d $FROMFOLDER* |rev| cut -d'/' -f1|rev|sed s/^/\"/g|sed s/$/\"/g))
SERVERDIRS=($(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER#$SERVER ls -d $FROMFOLDER* |rev| cut -d'/' -f1|rev|sed 's/ /\\ /g'))
SERVERDIRS=(`sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER#$SERVER ls -d $FROMFOLDER* |rev| cut -d'/' -f1|rev|sed 's/ /\\ /g'`)
How can I resolve these directories in to separate elements correctly?
If you're trying to read one array value per line instead of space-separated, then $() syntax won't help. Try readarray (Bash 4):
readarray SERVERDIRS < <(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER#$SERVER ls -l --time-style="long-iso" $FROMFOLDER | egrep '^d' | cut -d' ' -f8-)
or assign IFS and read with -d, -r, and -a set:
IFS=$'\n' read -d '' -r -a SERVERDIRS < <(sshpass -p $PASS ssh -oStrictHostKeyChecking=no $USER#$SERVER ls -l --time-style="long-iso" $FROMFOLDER | egrep '^d' | cut -d' ' -f8-)
or, really, any other answer to this SO question.
If you're unfamiliar with <() syntax, it's known as process substitution and will allow your variable to be set in your current environment rather than the instantly-discarded subshell that a pipe would create.
Bear in mind that this process is a little dangerous; filenames can also contain newlines, so it's usually much preferred to use find ... -print0.
If you only need to list directories, try this
ls -d /usr/local/src/*/
or
ls -d /path/to/your/directory/*/
You can then loop through all directories
#!/bin/bash
aa=`ls -d /usr/local/src/*/`
for dir in "${aa}[#]"
do
echo "$dir"
done
This works if dir names contain spaces.

Piping commands in a shell script

I want to write a script that opens a shell with a few tabs, and i want each tab to execute somthing automaticly. for some reason when i pipe the commands it does not work.
gnome-terminal \
--tab-with-profile=Titleable -t "A" \
--tab-with-profile=Titleable -t "B" -e "sudo tail -f /var/log/syslog" \
--tab-with-profile=Titleable -t "C" -e "sudo tail -f /var/log/syslog | grep txt"
for some reason for Tab A&B work but in C the grep txt is ignored.
Anyone know why?
Thanks
Mat
Use a shell to call your command:
gnome-terminal \
--tab-with-profile=Titleable -t "A" \
--tab-with-profile=Titleable -t "B" -e "sudo tail -f /var/log/syslog" \
--tab-with-profile=Titleable -t "C" -e 'sh -c "sudo tail -f /var/log/syslog | grep txt"'

Resources