Escaping commands in ssh connection via for loop - bash

#!/bin/bash
for x in ontwikkelkaart
do
echo "***";
echo ${x};
ssh ${x}#localhost "
find ~/public_html/wp-content/themes/ -type f -name "*.webp" | awk '{ gsub(".webp$", "") ; print $0 }' | xargs -i sh -c 'if [ ! -f "{}" ]; then echo {}.webp; fi' \;
"
done
I have the above script that connects to a server via SSH, it checks wether there are webp files with no jpg/png as source file; and echo's rm "filename".
The command:
find ~/public_html/wp-content/themes/ -type f -name "*.webp" | awk '{ gsub(".webp$", "") ; print $0 }' | xargs -i sh -c 'if [ ! -f "{}" ]; then echo {}.webp; fi' \;
Works when i run it on the command line of the server (via SSH), but when i try to do it in the for loop, it does not work because of the "".
Can someone (try to) explain why the above code does not work?

Try using a heredoc :
ssh -q -T ${x}#localhost 2> /dev/null <<'EOF'
find ~/public_html/wp-content/themes/ -type f -name "*.webp" | awk '{ gsub(".webp$", "") ; print $0 }' | xargs -i sh -c 'if [ ! -f "{}" ]; then echo {}.webp; fi' \;
EOF

Related

improve bash script to add one more action if success

I have a bash script to find out all non empty files under some directory. currently it only print the file name if found.
I would like to add one more line to print first 32 bytes in hex format.
#!/bin/sh
files=$(find /data/ -type f ! -empty)
for f in $files;
do
if [ -f "$f" ]; then
tr -d '\000' <$f | tr -c '\000' '\n' | grep -q -m 1 ^ || echo $f
fi
done
I try to add one more "&& xxd -g 1 -l 32 $f" at the end but it doesn't work!
Get the first 32 chars from the file:
dd if=so.bash ibs=32 count=1 2>/dev/null | od -h
dd gets the first 32 chars
od -h prints them in hex format
You could do it with xxd as well
xxd -l 32 $f
where $f is the file
#!/bin/bash
files=$(find /data/ -type f ! -empty)
for f in $files
do
if [ -f "$f" ]; then
tr -d '\000' <"$f" | tr -c '\000' '\n' | grep -q -m 1 ^ || echo $f
xxd -l 32 "$f"
echo ""
fi
done
the echo "" is to have an empty line between each file to split the output.
Suggesting one line gawk script:
gawk 'BEGINFILE{print FILENAME}/[^\x00]/{system("xxd -l 32 "FILENAME;nextfile}' $(find /data/ -type f ! -empty)
gawk Explanation
BEGINFILE{print FILENAME}
BEGINFILE{ # before processing a file
print FILENAME; # print the filename
}
/[^\x00]/{system("xxd -l 32 "FILENAME);nextfile}
/[^\x00]/{ # if records contains non NULL character
system("xxd -l 32 "FILENAME); # print first 32 hex charachters
nextfile; # read next file
}
Every command run in bash shell returns a value that’s stored in the bash variable “$?”.
Then the command can be split as below:
#!/bin/sh
files=$(find /data/ -type f ! -empty)
for f in $files;
do
if [ -f "$f" ]; then
tr -d '\000' <$f | tr -c '\000' '\n' | grep -q -m 1 ^
if [ $? -ne 0 ]; then
echo $f
xxd -l 32 $f
fi
fi
done

Perform a CAT in FOR and SSH

I do not have much experience in shell script, therefore I need your help. I have the following query, I need to make a CAT to the files that I list, but I have not managed to know where to place the command. Thank you:
read date
echo -e "RECORDINGS"
for e in $Rec
do
sshpass -p password ssh user#server find $e "-type f -mtime -10 -exec ls -gGh --full-time {} \;" | cut -d ' ' -f 4,7 | grep $date | awk -F " " '{print $2}'
done
Ignoring that much of the code here is outright dangerous --
find_on_server() {
local e_q
printf -v e_q '%q ' "$1"
sshpass -p password ssh user#server "bash -s $e_q" <<'EOF'
e=$1
find "$e" -type f -mtime -10 -exec ls -gGh --full-time {} \;
EOF
# ^^^ the above line MUST NOT BE INDENTED
}
find_on_server "$e" | cut -d ' ' -f 4,7 | grep $date | awk -F " " '{print $2}'

iterate over lines in file then find in directory

I am having trouble looping and searching. It seems that the loop is not waiting for the find to finish. What am I doing wrong?
I made a loop the reads a file line by line. I then want to use that "name" to search a directory looking to see if a folder has that name. If it exists copy it to a drive.
#!/bin/bash
DIRFIND="$2"
DIRCOPY="$3"
if [ -d $DIRFIND ]; then
while IFS='' read -r line || [[ -n "$line" ]]; do
echo "$line"
FILE=`find "$DIRFIND" -type d -name "$line"`
if [ -n "$FILE" ]; then
echo "Found $FILE"
cp -a "$FILE" "$DIRCOPY"
else
echo "$line not found."
fi
done < "$1"
else
echo "No such file or directory"
fi
Have you tried xargs...
Proposed Solution
cat filenamelist | xargs -n1 -I {} find . -type d -name {} -print | xargs -n1 -I {} mv {} .
what the above does is pipe a list of filenames into find (one at a time), when found find prints the name and passes to xarg which moves the file...
Expansion
file = yogo
yogo -> | xargs -n1 -I yogo find . -type d -name yogo -print | xargs -n1 -I {} mv ./<path>/yogo .
I hope the above helps, note that xargs has the advantage that you do not run out of command line buffer.

How to suppress out of grep in ksh

I have the below programme
query=$selectPart"${indxFile}"$filePart
if find /home/test -name "${cobolFile}"| xargs grep $query;then
print "${cobolFile}"
while read -r scriptFile;do
print " "
done < listScripts.txt
But the output of the grep query is being printed to stdout. How do I suppress this output?
The following should work
if find /home/test -name "${cobolFile}"| xargs grep $query | grep -v grep;then
if find /home/test -name "${cobolFile}"| xargs grep -q $query;then
This shd do the trick :D
if [ "$(find /home/test -name "${cobolFile}" -exec grep $query {} + )" ]
then
print "${cobolFile}"
while read -r scriptFile
do
print " "
done < listScripts.txt
fi

Count the deleted files Shell script

Can you tell me how can you count the files with the extension ".txt" you delete from a folder? Shell script in Unix
Thank you for your answer :)
I tried to delete them this way :
deleted=0
while read line
do
if test -d "$line"
then
for i in "$line"/*
do
if test -f "$i"
then
deleted=`ls -l $line |grep "*.o" | wc -l`
echo "From: " $line " I deleted : " $deleted
find . -type f -name "*.o" -exec rm -f {} \;
else
echo "Not file " $i
fi
done
else
echo "NOT a directory!"
fi
done
Try doing this :
LANG=C rm -v *.txt | grep -c "^removed "
An answer - though not necessarily the right one:
files=*.txt
ls -1 "$files" | wc -l
rm "$files"
Ruth

Resources