Unix Shell - find -print0 confusing me

This is Interesting: Free IT Magazines  
Home > Archive > Unix Shell > February 2007 > find -print0 confusing me





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author find -print0 confusing me
Charles Russell

2007-02-21, 7:16 pm

Why does the ascii nul character not appear in the string when it is
created by a backquote? (See below.) I am trying to figure out how to
handle spaces in pathnames.

#!/usr/bin/sh
echo "straight call to find"
# make ascii nul visible by swapping for @
find . -type d -name '*' -print0 | tr "\0" @
echo
echo "calling in backquotes"
echo `find . -type d -name '*' -print0 `| tr "\0" @

output:

$ puzl.sh
straight call to find
..@./spl it@./spl it
calling in backquotes
.../spl it./spl it2
Stephane CHAZELAS

2007-02-21, 7:16 pm

2007-02-21, 13:22(-06), Charles Russell:
> Why does the ascii nul character not appear in the string when it is
> created by a backquote? (See below.) I am trying to figure out how to
> handle spaces in pathnames.
>
> #!/usr/bin/sh
> echo "straight call to find"
> # make ascii nul visible by swapping for @
> find . -type d -name '*' -print0 | tr "\0" @
> echo
> echo "calling in backquotes"
> echo `find . -type d -name '*' -print0 `| tr "\0" @
>
> output:
>
> $ puzl.sh
> straight call to find
> .@./spl it@./spl it
> calling in backquotes
> ../spl it./spl it2


The NUL byte is the string terminator. For instance, the list of
arguments passed to a command is a list of NUL terminated
strings. So the NUL byte can't be passed in an argument to a
command.

Some shells like zsh (and possibly recent versions of ksh93)
are able to pass NUL characters to their builtin commands (and
only to the builtin ones).

The code above would have /worked/ with zsh.

--
Stéphane
Casper H.S. Dik

2007-02-21, 7:16 pm

Charles Russell <NOSPAM@bellsouth.net> writes:

>Why does the ascii nul character not appear in the string when it is
>created by a backquote? (See below.) I am trying to figure out how to
>handle spaces in pathnames.


Generally, the \0 byte is used as a terminator; it sees the strings but
ignores the NULL bytes.

What exactly are you try to do with the filenames? Handling in the
shell as a stream from find will be difficult.

Casper
Charles Russell

2007-02-21, 7:16 pm

Casper H.S. Dik wrote:
>
> Generally, the \0 byte is used as a terminator; it sees the strings but
> ignores the NULL bytes.
>
> What exactly are you try to do with the filenames? Handling in the
> shell as a stream from find will be difficult.
>


What I had in mind was something like this:

OLDIFS=$IFS
IFS=\0
for x in `find . -type d -name '*' -print0
do
echo will cd to $x;
cd $x;
$*;
cd $OLDPWD
done
IFS=$OLDIFS

From Stephane Chazelas' reply, it seems that I was barking up the wrong
tree entirely.

Stephane CHAZELAS

2007-02-21, 7:16 pm

2007-02-21, 14:22(-06), Charles Russell:
> Casper H.S. Dik wrote:
>
> What I had in mind was something like this:
>
> OLDIFS=$IFS
> IFS=\0
> for x in `find . -type d -name '*' -print0
> do
> echo will cd to $x;
> cd $x;
> $*;
> cd $OLDPWD
> done
> IFS=$OLDIFS
>
> From Stephane Chazelas' reply, it seems that I was barking up the wrong
> tree entirely.

[...]

With zsh,

IFS=$'\0'
for x in `find ... -print0`

will work.

But so will

for x in **/*(DN/)

Best is to use find's -exec.

--
Stéphane
Dan Mercer

2007-02-21, 7:16 pm


"Charles Russell" <NOSPAM@bellsouth.net> wrote in message news:HZ0Dh.15644$z6.11639@bigfe9...
: Why does the ascii nul character not appear in the string when it is
: created by a backquote? (See below.) I am trying to figure out how to
: handle spaces in pathnames.
:
: #!/usr/bin/sh
: echo "straight call to find"
: # make ascii nul visible by swapping for @
: find . -type d -name '*' -print0 | tr "\0" @

-name '*' is always true, so it's worthless. Using
-print0 is, AFAIK, only useful if passing the
stream to xargs or in the rare (one would hope)
case a filename would have embedded newlines.
The shell does not recognize "\0" - however,
echo, print and printf do. If all you are worried
about is names with spaces, then

find . -type d | while IFS= read dir

will be sufficient. However, if your sh is a true
Bourne shell (unlikely) then you'll have to reset
IFS within the while loop.

Dan Mercer


: echo
: echo "calling in backquotes"
: echo `find . -type d -name '*' -print0 `| tr "\0" @
:
: output:
:
: $ puzl.sh
: straight call to find
: .@./spl it@./spl it
: calling in backquotes
: ../spl it./spl it2


Charles Russell

2007-02-21, 7:16 pm

Dan Mercer wrote:
If all you are worried
> about is names with spaces, then
>
> find . -type d | while IFS= read dir
>
> will be sufficient. However, if your sh is a true
> Bourne shell (unlikely) then you'll have to reset
> IFS within the while loop.


Yes, the following succeeds in executing "pwd" in each directory.
OLDPWD is reset because $dir is a relative path. There is probably a
more elegant way to do it, but this is simple enough.

#!/usr/bin/sh
OLDPWD=$PWD
find . -type d | while IFS= read dir
do
echo $dir
cd $OLDPWD
cd "$dir"
pwd
done
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2009 webservertalk.com