How to pass a file name to sed|grep|awk command inside a variable assignment in unix - shell

Im trying to execute the following script to get the currentpath string from a file and pass it to find and replace in the next command. it works fine when running directly in the host server , but when tried to execute from jenkins build step, i'm getting a failure that file not found.
Error: sed: can't read test.txt: No such file or directory
Expected result is to get the "test.txt" file updated with "newPath" wherever the "currentPath" exists
code :
user="testuser"
host="remotehost"
newPath="/testpath/"
filetoUpdate="./test.txt" # this is a file
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa ${user}#${host} "currentPath="$(sed -n '/^PATH='/p $filetoUpdate | cut -d'=' -f2)" ; echo "currentPath was "$currentPath"" ; sed -n 's|$currentPath|$newPath|g' $filetoUpdate"

One of the problems is that locally defined variables newPath and filetoUpdate will not be available in script running on remote host. Also in this script only currentPath= will be executed on remote host, rest of the commands run locally.
I'd recommend to save script in a separate file.
test.sh:
newPath="/testpath/"
filetoUpdate="./test.txt"
currentPath=`sed -n '/^PATH=/p' $filetoUpdate | cut -d= -f2`
echo "currentPath was "$currentPath""
sed -i .bak "s|$currentPath|$newPath|g" $filetoUpdate
(I added -i for in-site editing)
And to run it with the command
ssh remotehost < t.sh

Related

How to store or capture variable from one directory to another and execute with cut command in Linux

I need to do as following, firstly I can read a server name from the text file line by line and do a grep command on it. The main task is to find the whole FQDN server name using only the hostname in the NB logs path and do other commands further. Here is the script I wrote but I am beginner in shell scripting and need your help. What do I missing here because I was thinking How to save a variable's value into another directory path and use it there? If I manually run these commands in command line it can give me what I do need it., thank you all..
#!/bin/sh
echo
echo "Looking for the whole backup client names?"
for server in `cat ./List_ServerNames.txt`;
do
cd /usr/openv/netbackup/logs/nbproxy/
return_fqdn=`grep -im1 '$server' "$(ls -Art /usr/openv/netbackup/logs/nbproxy/ | tail -n1 | cut -
d : -f8)" | cut -d " " -f 6 | cut -c -36 | cut -d "(" -f 1`
echo $return_fqdn
done
The output of script is down below:
Looking for the whole backup client names?

Checking file existence in Bash using commandline argument

How do you use a command line argument as a file path and check for file existence in Bash?
I have the simple Bash script test.sh:
#!/bin/bash
set -e
echo "arg1=$1"
if [ ! -f "$1" ]
then
echo "File $1 does not exist."
exit 1
fi
echo "File exists!"
and in the same directory, I have a data folder containing stuff.txt.
If I run ./test.sh data/stuff.txt I see the expected output:
arg1=data/stuff.txt
"File exists!"
However, if I call this script from a second script test2.sh, in the same directory, like:
#!/bin/bash
fn="data/stuff.txt"
./test.sh $fn
I get the mangled output:
arg1=data/stuff.txt
does not exist
Why does the call work when I run it manually from a terminal, but not when I run it through another Bash script, even though both are receiving the same file path? What am I doing wrong?
Edit: The filename does not have spaces. Both scripts are executable. I'm running this on Ubuntu 18.04.
The filename was getting an extra whitespace character added to it as a result of how I was retrieving it in my second script. I didn't note this in my question, but I was retrieving the filename from folder list over SSH, like:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1)
Essentially, I wanted to get the filename of the most recent file in a directory on a remote server. Apparently, head includes the trailing newline character. I fixed it by changing it to:
fn=$(ssh -t "cd /project/; ls -t data | head -n1" | head -n1 | tr -d '\n' | tr -d '\r')
Thanks to #bigdataolddriver for hinting at the problem likely being an extra character.

script Send command with SH

I would need a .sh script that allows me to read only the second line of a file and then send it to machine B.
Example file:
timestamp_pippo.csv
"Row1_skipped"
"Row2_send_to_machine"
the file is in the path:
C:\Program Files\Splunk\var\run\splunk\csv
only the second row "row2_send_to_machine" (contains a unix command) must be sent to machine B
once the command has been sent, the file timestamp_pippo.csv must be deleted.
can you help me? I'm not familiar with .sh
what I've managed to create so far is only this:
for a in $(C:\Program Files\Splunk\var\run\splunk\csv cat timestamp_pippo.csv|grep -v Row1_skipped);do
ssh unix_machine#11.111.111.11 $a
done
Since you want to retain the for loop:
for cmd in $(head -2 timestamp_pippo.csv | tail -1); do ssh <machine> $cmd; done
Though tbh, this is bad - if you actually extend this and use the loop, you will be doing multiple connects to the ssh machine. Better to create the batch file you want, then do one ssh and run the batch. Here's a decent explanation of running a local script on a remote host: https://unix.stackexchange.com/questions/313000/run-local-script-with-local-input-file-on-remote-host
Thanks for the reply. I've solved with this script:
path="/home/weblogic/testCSV/*.csv"
for a in $(ls -lrt $path|awk '{print $9}');do
#echo $(head -2 $a | tail -1)
ssh unix_machine#11.111.111.11 $(head -2 $a | tail -1)
rm $a
#echo "file $a removed"
break
#echo "send command"
done
Steps:
-check the file
-execute the old file
-remove the file
The command we have to send to machine B is in the second line of the file timestamp_pippo.csv.
Another question:
How I can authenticate me in the machine B?
BR

sed: There is no file or directory on ssh bash script

I want to save in a variable what the sed returns and then use it to compare with other text but when I try to save it I get this error.
This is the code:
#!/bin/bash
# Program name: test.sh
IPS=$HOME/Documentos/ips.txt
VERSION=/var/www/html/games/game/version
EOF=/dev/null
PASSWORD='password'
while read -r IP; do
echo $IP
sshpass -p $PASSWORD ssh -o 'StrictHostKeyChecking no' -o ConnectTimeout=1 -o ConnectionAttempts=1 $IP bash -c "'
REVISION=$(sed -n -e 6p $VERSION)
echo $REVISION
'" < $EOF
done < $IPS
This is the output:
192.168.232.69
sed: can't read /var/www/html/games/game/version: There is no file or directory
192.168.191.20
sed: can't read /var/www/html/games/game/version: There is no file or directory
192.168.191.19
sed: can't read /var/www/html/games/game/version: There is no file or directory
It should be clarified that when I use the command without saving it I do not have any errors and the file exist in every terminal.
Thanks to everyone for the help, I solved it using this link:
Assigning the value of a remote variable to a local variable in unix/linux

List files on remote server

I'm trying to run the following command:
ssh -A -t -i ~/.ssh/DevKP.pem -o StrictHostKeyChecking=no root#MyServer "for file in \`ls /root/spark/work/ \`; do echo 'file - ' $file; done"
The output is:
file -
file -
Connection to MyServer closed.
When I ran the command on the remote server itself:
for file in `ls /root/spark/work/ `; do echo 'file - ' $file; done
I get the output:
file - test1.txt
file - test2.txt
How do I get ti to work on the local server? it seems that it gets the right files (because there were two sysouts)
anyone has any idea?
thanks
You need to escape the $ in $file to make sure the remote shell interprets it instead of your local. You should also simplify the ls /root/.. to for file in /root/../*:
ssh root#MyServer "for file in /root/spark/work/* ; do echo 'file - ' \$file; done"

Resources