LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   Shell scripts issue (https://www.linuxquestions.org/questions/linux-general-1/shell-scripts-issue-771836/)

balakrishnay 11-27-2009 12:02 AM

Shell scripts issue
 
Hi all,

My scripts looks like this .. when i execute this script its says file does not exist even though file is present physically and if the file does not present in the file system then the output is null.

I am wrong somewhere .. ??

echo " enter file "
read name
for i in `find /apps12i -type f -name $name -printf %f `
do
if [ -e $i ]
then
echo "file exists"
else
echo "not exists "
fi
done

2. I want to send multiple attachments using mutt is possible ?

3. I want to change from mail address when i am sending mails through mutt.


Regards

ghostdog74 11-27-2009 12:05 AM

use a while read loop instead
Code:

find ... | while read file
do
  echo $file
done


catkin 11-27-2009 12:29 AM

You will get a better response to questions 2 and 3 if you put them in separate threads with relevant titles.

Regards the existing file(s) that is/are reported as not existing you can see which files are being tested by changing the code to
Code:

echo " enter file "
read name
for i in `find /apps12i -type f -name $name -printf %f `
do
    echo "DEBUG: file name is '$i'"
    if [ -e $i ]
    then
        echo "file exists"
    else
        echo "not exists "
    fi
done

File names including whitespace characters such as space will not be handled correctly by the script.

Regards null output for non-existing files, that is expected. The find command will not produce any output so the loop code will not be executed.

BTW:

balakrishnay 11-27-2009 12:52 AM

Thanks for your reply .. but i am not able to understand proplery

I have rewritten like this .. but still the same problem exists . can you please correct me.

I request you to please elaborate this while IFS= read -r -d '' this stmt.


echo " enter file "
read name
i=`find /apps12i -type f -name $name -print0` | while IFS= read -r -d '' $i
do
echo $i
done



Quote:

Originally Posted by catkin (Post 3771029)
You will get a better response to questions 2 and 3 if you put them in separate threads with relevant titles.

Regards the existing file(s) that is/are reported as not existing you can see which files are being tested by changing the code to
Code:

echo " enter file "
read name
for i in `find /apps12i -type f -name $name -printf %f `
do
    echo "DEBUG: file name is '$i'"
    if [ -e $i ]
    then
        echo "file exists"
    else
        echo "not exists "
    fi
done

File names including whitespace characters such as space will not be handled correctly by the script.

Regards null output for non-existing files, that is expected. The find command will not produce any output so the loop code will not be executed.

BTW:


ghostdog74 11-27-2009 01:08 AM

Code:

echo " enter file "
read name
find /apps12i -type f -name "$name"  | while read -r FILE
do
    echo $FILE
done


balakrishnay 11-27-2009 02:03 AM

Thanks for your reply ..... what if file does not exist .. my requirement is , if the file does not exist it should give me files does not exist message.

Regards



Quote:

Originally Posted by ghostdog74 (Post 3771047)
Code:

echo " enter file "
read name
find /apps12i -type f -name "$name"  | while read -r FILE
do
    echo $FILE
done



catkin 11-27-2009 02:14 AM

You changed
Code:

find /apps12i -type f -print0 | while IFS= read -r -d '' i
to
Code:

i=`find /apps12i -type f -name $name -print0` | while IFS= read -r -d '' $i
The change will prevent it working.

while IFS= read -r -d '' means "set IFS to the empty string and with that setting in use for this command only, run the "read" shell built-in command not treating any \ characters specially and only accepting the newline character as end-of-line indicator. The shell uses the characters in IFS as word-separators when parsing input into "words". The net effect of all this gobbledygook is to transfer exactly the file names that "find" prints, regardless of any weird characters in file names.

It is very defensive and robust. Most of the time ghostdog74's suggestion works perfectly well -- and is a lot simpler! :)

catkin 11-27-2009 02:18 AM

Quote:

Originally Posted by balakrishnay (Post 3771080)
Thanks for your reply ..... what if file does not exist .. my requirement is , if the file does not exist it should give me files does not exist message.

Regards

Code:

echo " enter file "
read name
found='NO'
find /apps12i -type f -name "$name"  | while read -r FILE
do
    echo $FILE
    found='YES'
done

[[ "$found" == 'NO' ]] && echo "File '$name' not found"


balakrishnay 11-27-2009 02:33 AM

i have executed this but .. the output is wrong ..

even though file exists .. its giving me file not found. i am really sorry please bare with me ..

testinst1.koel.co.in/apps12i]./check.sh
enter file
bala.txt
File 'bala.txt' not found
testinst1.koel.co.in/apps12i]./check.sh
enter file
APXVDRAL.rdf
/apps12i/oracle/KIRAN/apps/apps_st/appl/ap/12.0.0/reports/US/APXVDRAL.rdf
File 'APXVDRAL.rdf' not found

Regards



Quote:

Originally Posted by catkin (Post 3771087)
Code:

echo " enter file "
read name
found='NO'
find /apps12i -type f -name "$name"  | while read -r FILE
do
    echo $FILE
    found='YES'
done

[[ "$found" == 'NO' ]] && echo "File '$name' not found"



catkin 11-27-2009 06:52 AM

Quote:

Originally Posted by balakrishnay (Post 3771099)
i have executed this but .. the output is wrong ..

even though file exists .. its giving me file not found. i am really sorry please bare with me ..

testinst1.koel.co.in/apps12i]./check.sh
enter file
bala.txt
File 'bala.txt' not found
testinst1.koel.co.in/apps12i]./check.sh
enter file
APXVDRAL.rdf
/apps12i/oracle/KIRAN/apps/apps_st/appl/ap/12.0.0/reports/US/APXVDRAL.rdf
File 'APXVDRAL.rdf' not found

Regards

Better we "bear" with you -- "bare" is something different! :)

Sorry my stupid mistake -- the "while" loop is run in a subshell so any variables set in it are lost when it exits. :redface:

This one is tested
Code:

echo " enter file "
read name
while read FILE
do
    if [[ "$FILE" == '' ]]; then
        echo "$name not found"
    else
        echo "$FILE found"
    fi
done <<< $( find . -type f -name "$name" )


balakrishnay 11-27-2009 10:00 PM

Thank you !! very much. Finally it worked.

But i didn't understand the logic behind this .. can you please explain this.

echo " enter file "
read name
while read FILE
do
if [[ "$FILE" == '' ]]; then
echo "$name not found"
else
echo "$FILE found"
fi
done <<< $( find . -type f -name "$name" )

Regards


Quote:

Originally Posted by catkin (Post 3771310)
Better we "bear" with you -- "bare" is something different! :)

Sorry my stupid mistake -- the "while" loop is run in a subshell so any variables set in it are lost when it exits. :redface:

This one is tested
Code:

echo " enter file "
read name
while read FILE
do
    if [[ "$FILE" == '' ]]; then
        echo "$name not found"
    else
        echo "$FILE found"
    fi
done <<< $( find . -type f -name "$name" )



catkin 11-27-2009 10:51 PM

Quote:

Originally Posted by balakrishnay (Post 3771971)
can you please explain this.

The input to the read comes, non-intuitively, at the end of the do-done from a here string (scroll down to section 3.6.7) with the string itself being the output of $( find ...).

If the file does not exist, there is no output from the find command so the string is empty, hence the if [[ "$FILE" == '' ]].

It's easier to read your code if you put it in code tags (that's a link to instructions or you may prefer to use "Advanced Edit" mode which has a # button for code tags).

balakrishnay 11-27-2009 11:12 PM

Thanks .. nice explanation .

Regards



Quote:

Originally Posted by catkin (Post 3771990)
The input to the read comes, non-intuitively, at the end of the do-done from a here string (scroll down to section 3.6.7) with the string itself being the output of $( find ...).

If the file does not exist, there is no output from the find command so the string is empty, hence the if [[ "$FILE" == '' ]].

It's easier to read your code if you put it in code tags (that's a link to instructions or you may prefer to use "Advanced Edit" mode which has a # button for code tags).


balakrishnay 11-29-2009 10:29 PM

Hi Catkin,

My requirements seems to be changed again . I will explain you what i am trying to achieve.

I want to find multiple files in different directories with one find command and send this files to developers. This is my requirement and changed the code accordingly but it seems to be not working .

Code:

echo " enter how many files "
read no
echo " enter file "
read name
if [ $no = 1 ] ; then
while read FILE
do
    if [[ "$FILE" == '' ]]; then
        echo "$name not found"
    else
        echo "$FILE found"
done <<< $( find . -type f -name "$name" )
else
if [ no -gt 1 ] ; then
for j in {1..$no}
do
echo " enter file names "
read name
fn="-o -name $name"
done
while read FILE
do
    if [[ "$FILE" == '' ]]; then
        echo "$name not found"
    exit 1
    else
        echo "$FILE found"
    fi
done <<< $( find . -type f -name "$name" $fn )
fi
fi

Tried executing this code but it giving me error ..

testinst1.koel.co.in/apps12i]./check.sh
enter how many files
1
enter file
bala.txt
./check.sh: line 12: syntax error near unexpected token `done'
./check.sh: line 12: `done <<< $( find . -type f -name "$name" )'

Regards

Bala


Quote:

Originally Posted by balakrishnay (Post 3772003)
Thanks .. nice explanation .

Regards


chrism01 11-30-2009 12:14 AM

Code:

while
do
.
.
.
done < file

takes only one '<'
http://tldp.org/LDP/abs/html/redircb.html

catkin 11-30-2009 01:48 AM

Quote:

Originally Posted by balakrishnay (Post 3773905)

Tried executing this code but it giving me error ..

testinst1.koel.co.in/apps12i]./check.sh
enter how many files
1
enter file
bala.txt
./check.sh: line 12: syntax error near unexpected token `done'
./check.sh: line 12: `done <<< $( find . -type f -name "$name" )'

Unbalanced if-fi and do-done. Easier to find problem if use indentation. Here is untested correction
Code:

echo " enter how many files "
read no
echo " enter file "
read name
if [ $no = 1 ] ; then
  while read FILE
    do
        if [[ "$FILE" == '' ]]; then
            echo "$name not found"
        else
            echo "$FILE found"
        fi
    done <<< $( find . -type f -name "$name" )
elif [ no -gt 1 ] ; then
    for j in {1..$no}
    do
      echo " enter file names "
      read name
      fn="-o -name $name"
      while read FILE
      do
          if [[ "$FILE" == '' ]]; then
              echo "$name not found"
          exit 1
          else
              echo "$FILE found"
          fi
      done <<< $( find . -type f -name "$name" $fn )
    done
fi
#fi

But it would be easier for the user and the code if you simply looped until the user entered an empty line.
Code:

while true
do
    echo " enter file name (or no name to finish)"
    read name
    [[ "$name" == '' ]] && \exit 0
    while read filepath
    do
        if [[ "$filepath" == '' ]]; then
            echo "$name not found"
        else
            echo "$filepath found"
        fi
    done <<< $( find . -type f -name "$name" )
done


balakrishnay 12-01-2009 04:22 AM

Hi Catkin,

Is this possible to read more than one file at a time .. instead of reading one file at a time in this code ..

Code:

while true
do
    echo " enter file name (or no name to finish)"
    read name
    [[ "$name" == '' ]] && \exit 0
    while read filepath
    do
        if [[ "$filepath" == '' ]]; then
            echo "$name not found"
        else
            echo "$filepath found"
        fi
    done <<< $( find . -type f -name "$name" )
done

Regards

Bala

Quote:

Originally Posted by catkin (Post 3774051)
Unbalanced if-fi and do-done. Easier to find problem if use indentation. Here is untested correction
Code:

echo " enter how many files "
read no
echo " enter file "
read name
if [ $no = 1 ] ; then
  while read FILE
    do
        if [[ "$FILE" == '' ]]; then
            echo "$name not found"
        else
            echo "$FILE found"
        fi
    done <<< $( find . -type f -name "$name" )
elif [ no -gt 1 ] ; then
    for j in {1..$no}
    do
      echo " enter file names "
      read name
      fn="-o -name $name"
      while read FILE
      do
          if [[ "$FILE" == '' ]]; then
              echo "$name not found"
          exit 1
          else
              echo "$FILE found"
          fi
      done <<< $( find . -type f -name "$name" $fn )
    done
fi
#fi

But it would be easier for the user and the code if you simply looped until the user entered an empty line.
Code:

while true
do
    echo " enter file name (or no name to finish)"
    read name
    [[ "$name" == '' ]] && \exit 0
    while read filepath
    do
        if [[ "$filepath" == '' ]]; then
            echo "$name not found"
        else
            echo "$filepath found"
        fi
    done <<< $( find . -type f -name "$name" )
done



catkin 12-01-2009 10:16 AM

Don't understand what you want. The code reads a file name each time, not a file.

balakrishnay 12-01-2009 09:33 PM

I am sorry catkin,

Yes the same code should read more than one file name at one time ..

Regards


Quote:

Originally Posted by catkin (Post 3775797)
Don't understand what you want. The code reads a file name each time, not a file.


catkin 12-02-2009 01:02 AM

Quote:

Originally Posted by balakrishnay (Post 3776486)
I am sorry catkin,

Yes the same code should read more than one file name at one time ..

Regards

OK. Where from? From command line, user input or find command?

balakrishnay 12-02-2009 02:20 AM

From the user input and the same has to be passed to find command dynamically .

I will explain to you in detail.

Initially i will ask the user how many files does he need to find . for Ex:- user enters 2 then we should allow him to enter 2 file names .This shell script should find these 2 files along with the path.

Like this .. the user might enter any no of files to find .....

I have tried manually to find multiple files using find command it worked but i have problem taking file names dynamically.

Manually we can find like this ..

find /apps12i -type f -name filename1 -o -name filename2

Thank you !!



Quote:

Originally Posted by catkin (Post 3776623)
OK. Where from? From command line, user input or find command?



All times are GMT -5. The time now is 06:10 PM.