Part of your shell code looks like bash
code even though you use a #!
-line specifying csh
. csh
does not have a read
command, and this is why you get a signal 13
error.
Signal 13 is the PIPE signal, and it gets sent to a process when it's trying to write to a dead pipe (a pipe that nobody is reading from the other end of). The pipe is dead because the read
call failed in the while
-loop. It failed since it's not available in csh
.
If csh
had had a read
command, your loop would get filenames, but you would not have had any way of knowing where those filenames belonged (in what subdirectory) since you removed the directory path from them. You would therefore not be able to do much with them.
The easiest way for doing this would be to have find
ask the question to the user:
find . -type f -ok some-action '{}' ';'
This would ask for confirmation for each pathname before executing the some-action
utility with the pathname as its argument. It would ask with the complete command line that would be executed for the given pathname, so it's not quite what you might have in mind.
Note also that specifying -type f
will find all regular files, while your -name '*'
test will always be true for all types of files, including directories. I'm also using .
(the current directory) for the top-level directory for find
, which is what you seem to want to do with your DIR
variable.
To manually ask the user for input on each file, and at the same time handle pathnames correctly, the easiest would be to do something like
find . -type f -exec sh -c '
for pathname do
printf "process %s (%s)?\n" "${pathname##*/}" "$pathname" >&2
read answer
case $answer in [Nn]*) continue; esac
printf "processing %s...\n" "$pathname" >&2
# process "$pathname" here
done' sh {} +
This assumes a sh
-like shell, and will spawn sh -c
for batches of pathnames found by find
. The internal shell script would ask the user whether they'd like to process each individual pathname or not. If the user answers with a word starting with n
(case insensitive), the next pathname would be considered.
The "${pathname##*/}"
bit in the code is equivalent to "$( basename "$pathname" )"
as it removes everything in $pathname
up to and including the last slash.
The find
command acts as a sort of generator of pathnames for the for
-loop in the internal script, so piping pathnames or filenames to a while
-loop is never necessary.
Related: