S
S
Sergey2016-09-28 18:18:56
bash
Sergey, 2016-09-28 18:18:56

Problems with mv being called from a script?

There is a script that transfers files to ftp and then moves them to a separate folder
Due to the fact that file names can unpredictably have spaces and all sorts of special characters in the name, the file name is taken in single quotes for convenience by find's output
From the mv command line ' file1' 'file2'
target_folder succeeds with filenames containing any characters in the name, including spaces

files_xml=$(find $FROM -maxdepth 1 -name "*.xml" -mmin +1 -printf "'%f' ")
if [ -n "${files_xml}" ]; then
     echo "XML Files found, transferring"
     sendToFTP "$files_xml_escaped" && mv $files_xml $SENTPATH
else
     echo "XML files not found"
fi

As a result, when executing it, I get a bunch of errors (for each file):
mv: failed to execute stat for "'file.xml'": No such file or directory
I go to the directory, the file is there, stat is executed, mv also works manually.
Either I don't understand something, or hell, sir.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
A
Alexey Shumkin, 2016-09-29
@Kamikaze

when you write on the Bash mv 'file.xml' 'new-file.xml'command line, it is Bash that "expands" the quotes and starts mv already with parameters in them:
when you call in the script
mv $file ${new_file} ,
where $file='file.xml' (contains quotes)
then mv starts with a file name containing quotes, but there is no such file ... (actually, this is what abcd0x00 said )

R
RPG, 2016-10-05
@RPG

I didn’t really understand what the script does from the question, but I think this example contains the necessary:
​​- find -print0 ... xargs -0 guarantees the correct processing of special characters
- a separate function - process input data

send_and_move()
{
  stat "[email protected]" && echo mv "[email protected]" /tmp
}

export -f send_and_move
find -print0 | xargs -0 --no-run-if-empty bash -c 'send_and_move "[email protected]"'

A
Alexander, 2016-09-29
@keich

If there is a possibility of any special characters in the file names, then it is worth executing the script in perl or python. Well, if it's important, then you can do this (but there should not be single quotes in the file name):
files_xml=$(find $FROM -maxdepth 1 -name "*.xml" -mmin +1 -printf "'%f' ")
if [ -n "${files_xml}" ]; then
echo "XML Files found, transferring"
sendToFTP "$files_xml" && echo $files_xml | sed "s/'\s'/\n/g" | tr -d "'" | xargs -I{} mv {} $SENTPATH
​​else
echo "XML files not found"
fi

A
abcd0x00, 2016-09-30
@abcd0x00

Here's an example of how it's usually done.
You find the files you need, and then sed to compose a command (one or more) with them. When the command is ready, pipe it to sh.

The code
[[email protected] t]$ ll
итого 4
-rw-rw-r--. 1 guest guest    0 сен 30 13:08 a a.txt
-rw-rw-r--. 1 guest guest    0 сен 30 13:06 a.txt
-rw-rw-r--. 1 guest guest    0 сен 30 13:06 b.txt
-rw-rw-r--. 1 guest guest    0 сен 30 13:06 c.txt
drwxrwxr-x. 2 guest guest 4096 сен 30 13:19 d
[[email protected] t]$
[[email protected] t]$ ls
a a.txt  a.txt  b.txt  c.txt  d
[[email protected] t]$ 
[[email protected] t]$ files=$(find -name '*.txt')
[[email protected] t]$ 
[[email protected] t]$ echo "$files" | sed 's/.*/mv "&" d/'
mv "./b.txt" d
mv "./a.txt" d
mv "./c.txt" d
mv "./a a.txt" d
[[email protected] t]$ 
[[email protected] t]$ echo "$files" | sed 's/.*/mv "&" d/' | sh
[[email protected] t]$ 
[[email protected] t]$ ls
d
[[email protected] t]$ ls d
a a.txt  a.txt  b.txt  c.txt
[[email protected] t]$
[[email protected] t]$ ll d
итого 0
-rw-rw-r--. 1 guest guest 0 сен 30 13:08 a a.txt
-rw-rw-r--. 1 guest guest 0 сен 30 13:06 a.txt
-rw-rw-r--. 1 guest guest 0 сен 30 13:06 b.txt
-rw-rw-r--. 1 guest guest 0 сен 30 13:06 c.txt
[[email protected] t]$

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question