Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am at a loss here, trying to find out the reason why a shell script that is basically copying a couple of files and directories from one place to another will result in the content of two of the files (and only those two) being purged and replaced by link ../../modules/[name_of_file].

APPFOLDER="/home/opt/ke"
CMD_APPCOPY="cp -fr _opt/ke/* $APPFOLDER"
[...]     
echo "copying app-files to app-folder $APPFOLDER ..."
eval $CMD_APPCOPY
if [ $? -ne 0 ] ; then
   echo "could not copy app-files to app-folder $APPFOLDER"
   exit
fi

If I start the file copy by hand everything is fine.

cp -fr _opt/ke/* /home/opt/ke

But if I run the script the two files will be empty except for the link ../../modules/[name_of_file] part added on top of the empty file.

The two files in question are neither very huge or very small in size, the only thing that differentiate them from the other files in that directory is that they are of the Perl-Module .pm type. Their actual source destination is /home/xxx/xxx/deploy/KEB/_opt/ke/modules/ while the full target destination is /home/opt/ke/modules/. The script and the manual copy are run from /home/xxx/xxx/deploy/KEB/ of course.

Any idea/advice how this behaviour could be explained or what I should be looking for in order to fix the script is very much appreciated.

share|improve this question
1  
to verify your command does what you think it does: eval echo $CMD_APPCOPY. You should use an array to store a command: CMD_APPCOPY=(cp -fr _opt/ke/* $APPFOLDER); "${CMD_APPCOPY[@]}" (reference) –  glenn jackman Oct 11 '13 at 13:56
    
The * does not expand within double quotes. So that's wrong to start with. –  val0x00ff Oct 11 '13 at 13:58
    
@glennjackman the eval outputs cp -fr _opt/ke/cache _opt/ke/conf _opt/ke/modules _opt/ke/scripts _opt/ke/t /home/opt/ke and unfortunately switching to array storing didn't have any effect. –  Oliver N. Oct 11 '13 at 14:11
    
@glennjackman Ok this is funny, when I run the eval output by hand the same effect as running it by script will happen. Clearly I am not familar with the inner workings of the Linux filesystem !? :) So in order to fix this I should get rid of the * and do seperate copy commands for each subdir ? –  Oliver N. Oct 11 '13 at 14:15
    
Why are you using an eval? Can you not just run that variable as $CMD_APPCOPY. –  slm Oct 11 '13 at 14:27

1 Answer 1

up vote 2 down vote accepted

I think your issue is the use of eval. If you take your script and use arrays to store the commands prior to running this should be sufficient to execute those commands.

#!/bin/bash

CMD1=(echo "onecmd")
CMD2=(printf "%s\n" ascrip*)
CMD3='echo cmd3'

${CMD1[@]}
${CMD2[@]}
$CMD3

No need to run them through eval.

Example

$ ./ascript.bash 
onecmd
ascript.bash
cmd3

Debugging

You can see what's going on behind the scenes if you enable Bash's debug mode.

$ bash -x ./ascript.bash 
+ CMD1=(echo "onecmd")
+ CMD2=(printf "%s\n" ascrip*)
+ CMD3='echo cmd3'
+ echo onecmd
onecmd
+ printf '%s\n' ascript.bash
ascript.bash
+ echo cmd3
cmd3
share|improve this answer
    
I don't think this has anything to do with the eval. After the suggestions from the comment above I did some testing. If I run the expanded cp command (cp -fr _opt/ke/cache _opt/ke/conf _opt/ke/modules _opt/ke/scripts _opt/ke/t /home/opt/ke) by hand, the files are corrupted, too. But when running it in another order (like cp -fr _opt/ke/cache _opt/ke/t _opt/ke/conf _opt/ke/modules _opt/ke/scripts /home/opt/ke ) everything is fine again. So I assume the short directory name "t" is causing this (a bug maybe?). –  Oliver N. Oct 11 '13 at 14:50
    
Ok scrap that, I am seriously confused here. I retested this and now both commands work, regardless the order. The only thing I might have done is deleting the target directory instead of just cleaning its content. Sorry for the confusion, but unless the cp behaviour changes by the hour I have no explanation why it is working now. :/ –  Oliver N. Oct 11 '13 at 15:08
    
@OliverN. - I do a fair amount of scripting using this type of pattern and I've not needed to use eval like this. Only if I have variables nested inside of the array that I want to get expanded prior, do I use an eval. –  slm Oct 11 '13 at 15:22
    
@OliverN. I haven't analyzed your script in detail to figure out what causes this problem, but the eval raises a red flag. It WILL completely break for certain file names. If someone is allowed to choose a file name under _opt/ke, they are writing a code snippet that your script executes. eval is a delicate tool to be used sparingly and you are using it wrong. –  Gilles Oct 11 '13 at 22:56
    
@Gilles - yeah this wasn't well thought out, just something off the cuff. –  slm Oct 11 '13 at 23:43

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.