LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   while read line+subshell (https://www.linuxquestions.org/questions/programming-9/while-read-line-subshell-4175482097/)

defila 10-25-2013 04:10 AM

while read line+subshell
 
Hello guys,
I guess that this question has been asked probably too many times but my attempts are failing and I do not know why
Below code will connect to ftp and remove all files which are identified as empty ones (names are written to the "targets" text file)- the issue here is that it will remove the first line (close the subshell) and again will remove the 1st line(which is not present on the ftp anymore), and will go to the 2nd line etc .... which makes the execution quite ineffective

Code:

ftpH () {
ncftp -u $USER -p "$pwd" -P $port $IP <<+
ls
cd "$dir"/
rm "$line"
bye
+
}
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
files= ~/*
for f in $files
do
if [[ ! -s $f ]]; then
echo $(basename $f) >> ~/targets
cat ~/targets | while read line; do
ftpH 2>&1| zenity --width=400 --height=100 --progress --auto-close --pulsate --title "removing $line ...."
done
fi
done
IFS=$SAVEIFS

However, if I will try to execute something like this - it won't succeed, and there is some issue as well, do you have any Idea why ?

Code:

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
files= ~/*
for f in $files
do
if [[ ! -s $f ]]; then
echo $(basename $f) >> ~/targets
fi

while read line; do
ftpH 2>&1| zenity --width=400 --height=100 --progress --auto-close --pulsate --title "removing $line ...."
done < ~/targets
done
IFS=$SAVEIFS


catkin 10-25-2013 11:18 AM

files= ~/* sets variable files to an empty string and then tries to execute the lexically first file in your home directory with the later ones' names as arguments. Here's how it looks on my system:
Code:

c@CW9:~$ files= ~/*
bash: /home/c/Desktop: is a directory

You need to omit the space after the =

grail 10-25-2013 12:57 PM

Not only suggestion above but the whole idea of assigning to a variable first is flawed if there is any chance that a file should contain whitespace.

1. Simply use the glob to feed the for loop:
Code:

for f in $HOME/*
Note: using a variable name over an alias may also help remove unexpected results
Note 2: this method would also negate the need for altering IFS

2. Quote - Quote - Quote -- for the same reason as above, everywhere you have left $f unquoted allows for the potential of unexpected results

3. You are looking your home directory and creating a new file there (targets). This may not be an issue but would generally be a poor practice IMHO

4. You append each file name, without a path, to target and then read from target??
Code:

$ ls
file1
file2
file3

Assuming the above files are in your home directory and that the files are processed in the same order, file1 will be added and then a call to while loop to execute ftpH. Then file2 is added
so when while is called the first 'line' read is still file1 so call ftpH on this again and then next read will have file2 in 'line'. Lastly file3 is read in but while processes
from top down so file1 then file2 and lastly file3 are all passed to ftpH

You can probably see an issue with the logic here

5. Finally, the use of ~, $HOME and basename can all be avoided by simply cd'ing into your HOME directory prior to running the for loop

defila 10-28-2013 03:57 PM

Thanks !!! I was completely blind .... I have re-written it and it works now as desired :}

Quote:

Originally Posted by grail (Post 5052267)
Not only suggestion above but the whole idea of assigning to a variable first is flawed if there is any chance that a file should contain whitespace.

1. Simply use the glob to feed the for loop:
Code:

for f in $HOME/*
Note: using a variable name over an alias may also help remove unexpected results
Note 2: this method would also negate the need for altering IFS

2. Quote - Quote - Quote -- for the same reason as above, everywhere you have left $f unquoted allows for the potential of unexpected results

3. You are looking your home directory and creating a new file there (targets). This may not be an issue but would generally be a poor practice IMHO

4. You append each file name, without a path, to target and then read from target??
Code:

$ ls
file1
file2
file3

Assuming the above files are in your home directory and that the files are processed in the same order, file1 will be added and then a call to while loop to execute ftpH. Then file2 is added
so when while is called the first 'line' read is still file1 so call ftpH on this again and then next read will have file2 in 'line'. Lastly file3 is read in but while processes
from top down so file1 then file2 and lastly file3 are all passed to ftpH

You can probably see an issue with the logic here

5. Finally, the use of ~, $HOME and basename can all be avoided by simply cd'ing into your HOME directory prior to running the for loop



All times are GMT -5. The time now is 05:56 AM.