Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

File descriptors 3

Status
Not open for further replies.

goldenradium2001

Technical User
Mar 22, 2002
91
US
I'm trying to find out what file descriptors are in laymen's terms. I know that you can use exec x>file to assign a file descriptor to a file so that you don't even need to open that file using the filename (where x is the file descriptor number that you want to assign to the file).

However, to view the file, I'm told to use exec x<file. What is the point of that?? I thought I could just use the file descriptor number to open the file? I can just use vi file if this the way to view a file that I've assigned a file descriptor to.

Any help for a better definition of file descriptors and their usage would be GREATLY appreciated.

 
# Hi:

# you probably already know that unix defaults the
# standard input, standard # output, and
# standard error to descriptors 0, 1, 2 respectively.

# you can use the exec command to assign an unused descriptor
# to a file, and then redirect output to that descriptor:

exec 5>t.file

# send 3 lines of output to file t.file
print &quot;line 1&quot; 1>&5
print &quot;line 2&quot; 1>&5
print &quot;line 3&quot; 1>&5

# To answer your question, &quot;exec x < file&quot; can be used to
# change the input file descriptor so you get input from
# the file:

# save file descriptor 0 to 4 before changing 0 to t.file
exec 4<&0 0<t.file

# read back 3 lines from t.file
read line1
read line2
read line3
# restore descriptor 0 from 4 and close 4.
exec 0<&4 4<&-

# The problem with the above code is standard input has been
# changed, and I know of no way of getting any furthur input from
# the user without saving input descriptor 0 and later restoring it.
# maybe someone else has an idea?

#write back output to output (screen)
print &quot;line 1: &quot;$line1
print &quot;line 2: &quot;$line2
print &quot;line 3: &quot;$line3

# make sure standard input and output work normally
print &quot;press enter&quot;
read x
echo &quot;x is: &quot; $x

# careful; The result of the exec stays in effect until the file
# descriptor changs, closes, or the script terminates.

# I hope the above discussion hasn't confused you. I'd check your
# system's man ksh or man sh for exact info.

# Regards,

# Ed

 
Bravo Ed. Here is a novelty implementation of tac (there are better and much faster ways) using file descriptors.

Code:
#! /bin/sh

ERRMSG=&quot;Usage: `basename $0` file&quot;
if [ ! -t 0 ]; then
  echo &quot;$ERRMSG&quot; 1>&2
  exit 1
elif [ &quot;$#&quot; -eq 0 ]; then
  echo &quot;$ERRMSG&quot; 1>&2
  exit 1
elif [ ! -f $1 ]; then
  echo &quot;file $1 not found&quot; 1>&2
  echo &quot;$ERRMSG&quot; 1>&2
  exit 1
fi
  
COUNT=`cat $1 | wc -l`
IDX=0
exec 4< $1

exec 6<&0
while [ &quot;$IDX&quot; -lt &quot;$COUNT&quot; ]; do
  if [ &quot;`expr $IDX % 2`&quot; -eq 0 ]; then
    sed '$!{h;N;/.*\n/ s///;p;g;}' <&4 | exec 5<&0
  else
    sed '1!{
      $!{h;N;/.*\n/ s///;p;g;}
    }' <&5 | exec 4<&0
  fi
  IDX=$(($IDX + 1))
done

if [ &quot;`expr $IDX % 2`&quot; -eq 0 ]; then
  cat <&4
else
  cat <&5
fi

exec 0<&6 6<&- 5<&- 4<&-

btw - There is almost always a more straightforward way to script than resorting to file descriptors. Exceptions are when stderr, exit status, doing things like tee and doing these things along a piped series of commands somewhere. Understanding these, however, will help you better understand Unix. Cheers,
ND [smile]

bigoldbulldog@hotmail.com
 
Ed, nice summary - get a star! vlad
+---------------------------+
|#include<disclaimer.h> |
+---------------------------+
 
Nate/Vlad:

Thanks for the kind words! It means a lot coming from a couple of unix &quot;heavy weights&quot; such as yourselfs.

It's all about sharing information.

Ed
 
Let's say I have assigned file descriptor 4 to the file filedesc:

# exec 4<>filedesc

I write to it using:

# print &quot;line1&quot; 1>&4

Then I try to view it using:

# cat <&4
but it doesn't work. I cat the actually file:

#cat filedesc

And it shows me what I put in there. Any help?? THanks.
 
another question, i was reading about the exec command only being able to take file descriptors 4-9. Is this true? If so, what is 3 used for?

Thanks.
 
Goldenradium:

Sorry it's taken so long to get back to you. I've been ill.

You are attempting to open file descriptor 4 for both reading and writing:

# exec 4<>filedesc

I only recently learned of this syntax from reading &quot;The Korn Shell, Unix
& Linux Programming Manual&quot;, by Anatole Olczak. Like yourself, I could not
get the read/write syntax to work and I tried it under Solaris 7 and
SCO Open Server V ksh. I also tried the ksh93 version of ksh, dtksh,
and it fails. It also fails under Red Hat Linux 7.1 bash.
(the error is not fatal, the &quot;cat <&4&quot; just doesn't do anything).

Of course, opening a separate descriptor for writing works under all
my environments:

exec 5>filedesc
exec 3<filedesc

print &quot;line 1&quot; 1>&5

cat <&3

To answer your other question, under the environments listed above,
there's nothing special about file descriptor 3; It's the same as 4 to 9.
Apparently, in your environment there is a difference?

It's my guess that opening a descriptor for reading/writing is a relatively new
construct, and is available only in some ksh93 versions, but I could
be wrong.


Ed
 
OLDED:

# The problem with the above code is standard input has been
# changed, and I know of no way of getting any furthur input from
# the user without saving input descriptor 0 and later restoring it.
# maybe someone else has an idea?

I haven't got the time to look at this in depth but have you tried &quot;read ANSWER < /dev/tty&quot; to get more user input.

maybe or maybe not?

Adam
 
umm ... that kinda spoils any redirection from files ...
if you get from /dev/tty (even if that is your standard input in the first place, it isn't if these aren't run from the command line), you can't pipe into a script that uses that from the command line,
e.g. '
Code:
myscript.sh < myinput.txt
' would fail at the /dev/tty point, for instance.

umm ... although do correct me if i'm wrong :)
 
Adam:

In my original post, I agreed with you as far as saving the original 0 file descriptor, and later restoring it. However, Goldenradium's later question involves opening a descriptor for reading-and-writing (not just one).

According to Anatole Olczak's text, Goldenradium's code should work:

# print &quot;line1&quot; 1>&4

Then I try to view it using:

# cat <&4

Since I don't have access to a shell supporting &quot;<>&quot;, I don't know if Olczak is right or not. I agree with the Bigoldbulldog; you probably don't want to mess with file descriptors if you don' have to, but it's an interesting technical exercise.

Regards,

Ed
 
OK JAD,

Like I said I didn't have time to look at the problem but I often get around nested loops which take the previous loops answer by stopping the loop by reading /dev/tty, that way I can reuse the same variable for my reads.

My reply was just meant to say &quot;have a quick try with this&quot; and if not go back to the drawing board.

Adam
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top