| |
SEAS-Net
Frequently Asked Questions
Contents:
- Intro
- Reading the online documentation
- How do I make my backspace key
work?
- What printers are available and
how do I print to them?
- How do I find out how much paper
quota I have left to print?
- How do I find out how much disk
space I am using?
- Where do I report problems with
equipment?
- How can I dial into SEAS-Net from
home?
- What type of modem file transfer
protocols does SEAS-Net have?
- How do I use ``kermit'' to transfer
a file?
- How do I remove a file whose name
begins with a - ?
- How do I get a recursive directory
listing?
- How do I get the current directory
into my prompt?
- How do I read characters from a
terminal without requiring the user to hit RETURN?
- How do I read characters from the
terminal in a shell script?
- How do I check to see if there are
characters to be read without actually reading?
- How do I rename *.foo to *.bar,
or change file names to lowercase?
- Why do I get [some strange error
message] when I `rsh host command'?
- How do I find out the creation
time of a file?
- How do I use rsh without having
the rsh hang around until the remote command has completed?
- How do I truncate a file?
- How do I {set an environment variable,
change directory} inside a program or shell script and have that change
affect my current shell?
- Why doesn't find's {} symbol do
what I want?
- How do I redirect stdout and stderr
separately in csh?
- How do I set the permissions on
a symbolic link?
- When someone refers to 'rn(1)'
or 'ctime(3)', what does the number in parentheses mean?
- What does {awk,grep,fgrep,egrep,biff,cat,gecos,nroff,troff,tee,bss,rc}
stand for?
- How do I ``undelete'' a file?
- How can a process detect if it's
running in the background?
- How can an executing program determine
its own pathname?
- How do I tell inside .cshrc if
I'm a login shell?
- How do I use popen(3) to open a
process for reading AND writing?
- How do I run 'passwd', 'ftp', 'telnet',
'tip' and other interactive programs from a shell script or in the background?
- How do I sleep() in a C program
for less than one second?
- What's wrong with having '.' in
your $PATH ?
- Is it possible to reconnect a process
to a terminal after it has been disconnected, e.g. after starting a
program in the background and logging out
- Intro
While the system appears to be confusing, vertually everything is documented,
so mewhere. the trick is quickly locating the relevent information.
This document attempts to give you some guide lines on how to go about
getting help about a perticular subject matter. Basically there are
four ways of getting help on an aspect of the system:
- Reading the manual page(s).
- Reading the Frequently asked questions documentation.
- Asking a lab manager or instructor.
- Sending email to 'help@seas.smu.edu'.
- Calling the SEAS Help Desk at 768-7327
(311-A Caruth Hall)
- Reading the
online documentation
The absolute best way to obtain factual information
about a command is by Reading its online manual page(s).
Some day you may encounter the phrase 'RTFM', which stands
for 'Read the Fine Manual' (except 'F' doesn't really stand for
"Fine"). If you ask someone a question and they tell you to RTFM, it's
an indication that you haven't done enough research. For instance, if
you are having trouble removing a file whose name begins with a "-", check
the man page for rm. It might tell you what you need
to know. When people use terminology like 'read(2), they are
referring to the 'read' man page in section 2 of the manual (which
you would see by using 'man 2 read').
There are a couple of commands that will help
you in your quest for the right "manual" page.
-
- apropos
- The apropos command shows which manual
sections contain instances of any of the given keywords in their
title. Each word is considered separately and the case of letters
is ignored. Words that are part of other words are listed. Thus,
looking for the word compile hits all instances of `compiler' also.
If the line starts `name(section) ...' you can do `man section name'
to get the documentation for it.
For example, the following command line
lists all commands that have to do with formatting:
To then access the reference page for
the printf subroutine that you see listed, type:
-
- whatis
- The whatis command looks up a given
command and gives the header line from the manual section. You can
then run the man(1) command to get more information. If the line
starts ``name(section) ...'' you can do ``man section name'' to
get the documentation for it. Try:
whatis ed
and then you should do:
-
to get the manual page.
-
-
-
- man
- The basic function of this command is
to provide online displays of reference pages. You can use options,
however, to direct the man command to display one line summaries
of reference pages which contain specific keywords, to display one
line summaries of specific reference pages, to use special formatting
options when preparing the reference page for display or printing,
and to search alternate reference page directories for specified
reference pages.
If an option is not used, the man command
formats and displays one or more specified reference pages. If
there are multiple reference pages which match a specified name,
only the first matching reference page is displayed. If there
are multiple matches in a section for a specified name, the matching
page in the first alphabetically occurring subsection is displayed.
If you specify the man command with a section
argument, the man command looks in that section of the reference
pages for the specified page titles. A section consists of a number
in the range 0 to 9, optionally followed by an alphanumeric subsection.
If a section is omitted, the man command
searches all sections of the reference pages. The man command
displays commands (both standard and local) over subroutines in
system libraries, and displays the first occurrence it finds,
if any.
As an example, to get information on the
cc (c compiler) command you would type the command:
- How do I
make my backspace key work?
There are currently two well known backspace
keys, a ASCII 8 or Control-H and a Delete. Murphys law says that whatever
you are logging into will undoubtably use the other one from the terminal
you have. The easiest way to resolve the problem is to type the command:
Where BS-key is the key on the
keyboard that would normally be your backspace. Note: YOU DO
NOT WANT TO USE AN ARROW KEYas your backspace key. Arrow keys
are meant for cursor movement inside of applications not for text handling
on the command line.
- What printers
are available and how do I print to them?
Currently there are several printers available;
below is a list of the printer and the type of file expected to be printed
on it.
| Printer Name |
Type |
Location |
Data Expected |
| sic_lp |
Line |
SIC Public Termina Area |
Program listings, text, etc. |
| sic_si |
Laser |
SIC Public Terminal Area |
Postscript |
| clem15 |
Line |
Clements Hall Basement |
Program listings, text, etc. |
| ch_lp |
Line |
Caruth Public Terminal Area |
Program listings, text, etc. |
| ch_si |
Laser |
Caruth Public Terminal Area |
Postscript |
| ch_215 |
Line |
Room 215 Caruth |
Program listings, text, etc. |
| me_lab |
Laser |
CME lab1 Terminal Area |
Postscript |
Accessing a printer is done usually via
the -P option of lpr(1). To print a program listing
on the printer in Clements Lab for example:
- How do I
find out how much paper quota I have left to print?
The command pquota(1) will
give you a summarized listing of how many paper units you have left
to print. See the manual page for paper_policy(1) for
information on how this is calculated.
- How do I find
out how much disk space I am using?
The command du(1) will
answer this. From your home directory type the command:
This will return the number of 1024 byte blocks
your account is consuming. Compression of older data
or programs is highly recommended. See the man pages for gzip(1)
and gunzip(1) for more information.
Also, if you are subject to disk quotas, the
dquota(1) command will return the amount of disk
quota you've been assigned and the current amount you are using.
- Where do I
report problems with equipment?
Generally you report problems to your
TA or instructor. If there really appears to be a serious problem
of some kind sending email to help@seas.smu.edu will generally
get someones attention.
- How can I dial
into SEAS-Net from home?
Currently there is one primary dial in rotary. The number is (214)-768-1710.
This number will support modems from 1200 baud to 19200 baud using 8
bits, no parity, and 1 stop bit.
- What type of
modem file transfer protocols does SEAS-Net have?
We have several, what you can use from home may be a different question.
Basically we recommend using kermit(1). It's simple
enough to live thru whatever connection you established to get here.
It's possible to use the rz/sz Xmodem programs but
sometimes they don't work for whatever reason. As it is we continually
monitor kermits functionallity. If you suspect a problem on this send
send email about it to 'help@seas.smu.edu'. If they tell you
kermit's working, the problem is more than likely on your end.
- How do I use
``kermit'' to transfer a file?
After you have logged into the SEAS network, you can invoke kermit by
typing kermit. If you are transfering a binary file,
type 'set file type binary' at the CKermit>
prompt which you will see after kermit starts up. If, on the otherhand,
you are transfering a text file, type 'set file type text'
after kermit starts up. To be safe, you should set the same file type
in the communications package you are using on your PC. You will need
to check the documentation for your communications package to determine
how to to set the kermit file transfer type.
After that, type 'send your_file_name'
at the kermit prompt to send a file from the SEAS machine to your
PC. If you are sending a file from your PC to one of the SEAS machines,
you type 'receive file_name'. Kermit will
tell you to escape back to your local system and give the receive
command. Kermit will time out after a short time so you need to be
ready to take the appropriate action on your side promptly.
The escape command is different for each communications
program. You will need to check the documentation for your communications
program to determine the corect response. After the transfer is started,
things should proceed until your file has been transferred.
- How do I remove
a file whose name begins with a - ?
Figure out some way to name the file so that it doesn't begin with a
dash. The simplest answer is to use:
(assuming '-filename' is in the current directory, of course.) This
method of avoiding the interpretation of the "-" works with other commands
too.
Many commands, particularly those that have
been written to use the getopt(3) argument parsing
routine, accept a "--" argument which means "this is the last option,
anything after this is not an option", so your version of rm might
handle '>rm -- -filename'. Some versions of rm that don't use getopt()
treat a single "-" in the same way, so you can also try 'rm - -filename'.
- How do I get
a recursive directory listing?
One of the following may do what you want:
- ls -R (not all versions of ls accept '-R')
- >find . -print (should work everywhere)
- du -a . (shows you both the name and size)
If you're looking for a wildcard pattern that
will match all '.c' files in this directory and below, you won't find
one, but you can use:
find . -name '*.c' -print
find is a powerful program.
Learn about it.
- How do I get
the current directory into my prompt?
It depends which shell you are using.
It's easy with some shells, hard or impossible with others.
C Shell (csh):
- Put this in your .cshrc - customize
the prompt variable the way you want.
alias setprompt 'set prompt="${cwd}% "'
setprompt # to set the initial prompt
alias cd 'chdir \\!* && setprompt'
# if you need pushd and popd
alias pushd 'pushd \\!* && setprompt'
alias popd 'popd \\!* && setprom
Bourne Shell (sh):
- If your machine has a newer version
of the Bourne Shell (SVR2 or newer) you can use a shell function
to make your own command, 'xcd' say:
xcd() { cd $* ; PS1="`pwd` $ ";
}
Korn Shell (ksh):
- Put this in your .profile file:
PS1='$PWD $ ' If you just want the last component of the directory, use:
PS1='${PWD##*/} $ '
T C shell (tcsh):
- Tcsh is a popular enhanced version of
csh with some extra builtin variables (and many other features):
%~ the current directory, using ~ for $HOME
%d or %/ the full pathname of the current
directory
%c or %. the trailing component of the
current directory
so you can do: set prompt='%~ '
BASH:
- \w in $PS1 gives the full pathname of
the current directory, with ~ expansion for $HOME; \W gives the
basename of the current directory. So, in addition to the above
sh and ksh solutions, you could use:
PS1='\w $ ' or PS1='\W
$ '
- How do I read
characters from a terminal without requiring the user to hit RETURN?
If you don't want to tackle setting the terminal parameters yourself
(using the ioctl(2) system call) you can let the stty
program do the work - but this is slow and inefficient, and you should
change the code to do it right some time, (see the CBREAK
mode in the ioctl(2) manual page):
#include
main()
{
int c;
printf("Hit any character to continue\\n");
/*
* ioctl() would be better here; only lazy
* programmers do it this way:
*/
system("/bin/stty cbreak"); /* or "stty raw" */
c = getchar();
system("/bin/stty -cbreak");
printf("Thank you for typing %c.\\n", c);
exit(0);
}
You might like to check out the documentation
for the curses library of portable screen functions.
Often if you're interested in single-character input/output like this,
you're also interested in doing some sort of screen display control,
and the curses library provides various portable routines for both
functions.
- How do I read
characters from the terminal in a shell script?
In sh, use read. It is most common to use a loop like:
while read line
do
...
done
In csh, use "$<" like this:
while ( 1 )
set line = "$<"
if ( "$line" == "" ) break
...
end
Unfortunately csh has no way
of distinguishing between a blank line and an end-of-file.
- How do I check
to see if there are characters to be read without actually reading?
Certain versions of UNIX provide ways to check whether characters are
currently available to be read from a file descriptor. In BSD, you can
use select(2). You can also use the FIONREAD ioctl
(see tty(4)), which returns the number of characters
waiting to be read, but only works on terminals, pipes and sockets.
In System V Release 3, you can use poll(2), but that
only works on streams. In Xenix - and therefore Unix SysV r3.2 and later
- the rdchk() system call reports whether a read()
call on a given file descriptor will block.
There is no way to check whether characters
are available to be read from a FILE pointer. (You could poke around
inside stdio data structures to see if the input buffer is nonempty,
but that wouldn't work since you'd have no way of knowing what will
happen the next time you try to fill the buffer.)
Sometimes people ask this question with the
intention of writing:
if (characters available from fd)
read(fd, buf, sizeof buf);
in order to get the effect of a nonblocking
read. This is not the best way to do this, because it is possible that
characters will be available when you test for availability, but will
no longer be available when you call read. Instead, set the ,strong>O_NDELAY
oflag (which is also called FNDELAY under BSD) using the F_SETFL
option of fcntl(2).
- How
do I rename *.foo to *.bar, or change file names to lowercase?
Why doesn't 'mv *.foo *.bar' work? Think about how the shell expands
wildcards. "*.foo" and "*.bar" are expanded before the mv command ever
sees the arguments. Depending on your shell, this can fail in a couple
of ways. CSH prints "No match." because it can't match "*.bar". SH executes
"mv a.foo b.foo c.foo *.bar", which will only succeed if you happen
to have a single directory named "*.bar", which is very unlikely and
almost certainly not what you had in mind.
Depending on your shell, you can do it with
a loop to mv each file individually. If your system
has basename, you can use:
- csh:
foreach f ( *.foo ) set base=`basename $f
.foo` mv $f $base.bar end
- sh:
for f in *.foo; do
base=`basename $f .foo`
mv $f $base.bar
done
If you don't have basename
or want to do something like renaming foo.* to bar.*, you can
use something like sed to strip apart the original
file name in other ways, but the general looping idea is the same.
You can also convert file names into mv commands
with sed, and hand the commands off to sh
for execution. Try:
ls -d *.foo | sed -e 's/.*/mv & &/'
-e 's/foo$/bar/' | sh
Shell loops like the above can also be used
to translate file names from upper to lower case or vice versa.
You could use something like this to rename uppercase files to
lowercase:
- csh:
foreach f ( * )
mv $f `echo $f | tr '[A-Z]' '[a-z]'`
end
- sh:
for f in *; do
mv $f `echo $f | tr '[A-Z]' '[a-z]'`
done
- ksh:
typeset -l l
for f in *; do
l="$f"
mv $f $l
done
- Why do I get
[some strange error message] when I `rsh host command'?
If your remote account uses the C shell, the remote host will fire up
a C shell to execute 'command' for you, and that shell will read your
remote .cshrc file. Perhaps your .cshrc contains a stty,
biff or some other command that isn't appropriate for
a non-interactive shell. The unexpected output or error message from
these commands can screw up your rsh in odd ways.
Fortunately, the fix is simple. There are, quite
possibly, a whole *bunch* of operations in your .cshrc
(e.g., 'set history=N') that are simply not worth doing except in
interactive shells. What you do is surround them in your .cshrc
with:
if ( $?prompt ) then operations....
endif
and, since in a non-interactive shell "prompt"
won't be set, the operations in question will only be done in interactive
shells.
You may also wish to move some commands to your
.login file; if those commands only need to be done
when a login session starts up (checking for new mail, unread news
and so on) it's better to have them in the .login
file.
- How do I find
out the creation time of a file?
You can't - it isn't stored anywhere. Files have a last-modified time
(shown by 'ls -l'), a last-accessed time (shown by 'ls -lu')
and an inode change time (shown by 'ls -lc'). The latter is
often referred to as the "creation time" - even in some man pages -
but that's wrong; it's also set by such operations as mv, ln,
chmod, chown and chgrp.
The man page for stat(2) discusses
this.
- How do I use
rsh without having the rsh hang around until the remote command has
completed?
For instance, try doing rsh machine
'sleep 60 &' and you'll see that the rsh won't
exit right away. It will wait 60 seconds until the remote sleep
command finishes, even though that command was started in the background
on the remote machine. So how do you get the 'rsh' to exit immediately
after the 'sleep' is started?
The solution - if you use csh on the remote
machine:
rsh machine -n 'command >&/dev/null </dev/null
&'
If you use sh on the remote machine:
rsh machine -n 'command >/dev/null 2>&1
</dev/null &'
Why? "-n" attaches rsh's stdin to /dev/null
so you could run the complete rsh command in the background on the
LOCAL machine. Thus "-n" is equivalent to another specific "< /dev/null".
Furthermore, the input/output redirections on the REMOTE machine (inside
the single quotes) ensure that rsh thinks the session can be terminated
(there's no data flow any more.)
Note: The file that you
redirect to/from on the remote machine doesn't have to be /dev/null;
any ordinary file will do. In many cases, various parts of these complicated
commands aren't necessary.
- How do I truncate
a file?
The BSD function ftruncate() sets the length of a file.
Xenix - and therefore SysV r3.2 and later - has the chsize() system
call. For other systems, the only kind of truncation you can do is truncation
to length zero with creat() or open(..., O_TRUNC).
- How do I {set
an environment variable, change directory} inside a program or shell
script and have that change affect my current shell?
In general, you can't, at least not without making special arrangements.
When a child process is created, it inherits a copy of its parent's
variables (and current directory). The child can change these values
all it wants but the changes won't affect the parent shell, since the
child is changing a copy of the original data.
Some special arrangements are possible. Your
child process could write out the changed variables, if the parent
was prepared to read the output and interpret it as commands to set
its own variables.
Also, shells can arrange to run other shell
scripts in the context of the current shell, rather than in a child
process, so that changes will affect the original shell.
- Why doesn't
find's {} symbol do what I want?
find has a -exec option that will execute a particular
command on all the selected files. Find will replace any "{}" it sees
with the name of the file currently under consideration.
So, some day you might try to use find
to run a command on every file, one directory at a time. You might
try this:
find /path -type d -exec command {}/\\*
\\;
hoping that find will execute, in turn:
command directory1/*
command directory2/*
...
Unfortunately, find only expands the "{}" token
when it appears by itself. Find will leave anything else like "{}/*"
alone, so instead of doing what you want, it will do:
command {}/*
command {}/*
...
once for each directory. This might be a bug,
it might be a feature, but we're stuck with the current behaviour.
- How do I redirect
stdout and stderr separately in csh?
In csh, you can redirect stdout with ">", or stdout and stderr together
with ">&" but there is no direct way to redirect stderr only. The best
you can do is:
( command >stdout_file ) >&stderr_file
which runs command in a subshell; stdout
is redirected inside the subshell to stdout_file, and both
stdout and stderr from the subshell are redirected to stderr_file,
but by this point stdout has already been redirected so only stderr
actually winds up in stderr_file.
- How do I set
the permissions on a symbolic link?
Permissions on a symbolic link don't really mean anything. The only
permissions that count are the permissions on the file that the link
points to.
- When someone
refers to 'rn(1)' or 'ctime(3)', what does the number in parentheses
mean?
It looks like some sort of function call, but it isn't. These numbers
refer to the section of the Unix manual where the appropriate
documentation can be found. You could type 'man 3 ctime' to look up
the manual page for ctime in section 3 of the manual.
- What does {awk,grep,fgrep,egrep,biff,cat,gecos,nroff,troff,tee,bss,rc}
stand for?
awk
- This language was named by its authors,
Al Aho, Peter Weinberger and Brian Kernighan.
grep
- Global Regular Expression Print
grep comes from
the ed command to print all lines matching a certain pattern g/re/p
where 're' is a regulat expression.
fgrep
- Fixed GREP
fgrep searches for
fixed strings only. The "f" does not stand for "fast" - in fact,
"fgrep foobar *.c" is usually slower than "egrep foobar *.c" (Yes,
this is kind of surprising. Try it.)
Fgrep still has
its uses though, and may be useful when searching a file for a larger
number of strings than egrep can handle.
egrep
- Extended GREP, Egghead grep
egrep uses fancier
regular expressions than grep. Many people use egrep all the time,
since it has some more sophisticated internal algorithms than grep
or fgrep, and is usually the fastest of the three programs.
cat
- CATenate
catenate is an obscure
word meaning "to connect in a series", which is what the "cat" command
does to one or more files. Not to be confused with C/A/T, the Computer
Aided Typesetter.
gecos
- General Electric Comprehensive Operating
System
When GE's large
systems division was sold to Honeywell, Honeywell dropped the "E"
from "GECOS".
Unix's password
file has a pw_gecos field. The name is a real holdover
from the early days. Dennis Ritchie has reported:
"Sometimes
we sent printer output or batch jobs to the GCOS machine. The gcos
field in the password file was a place to stash the information for
the $IDENT card. Not elegant."
nroff, troff, groff
- New ROFF, Typesetter new ROFF, GNU's roff
These are descendants
of "roff", which was a re-implementation of the Multics "runoff"
program (a program that you'd use to "run off" a good copy of a
document).
tee
- T
From plumbing terminology
for a T-shaped pipe splitter.
bss
- Block Started by Symbol
Dennis Ritchie says:
"Actually the acronym (in
the sense we took it up; it may have other credible etymologies) is
"Block Started by Symbol." It was a pseudo-op in FAP (Fortran Assembly
[-er?] Program), an assembler for the IBM 704-709-7090-7094 machines.
It defined its label and set aside space for a given number of words.
There was another pseudo-op, BES, "Block Ended by Symbol" that did
the same except that the label was defined by the last assigned word
+ 1. (On these machines Fortran arrays were stored backwards in storage
and were 1-origin.)
The usage is
reasonably appropriate, because just as with standard Unix loaders,
the space assigned didn't have to be punched literally into the
object deck but was represented by a count somewhere."
biff
- This command, which turns on asynchronous
mail notification, was actually named after a dog at Berkeley.
We can confirm the
origin of biff, if you're interested. Biff was Heidi Stettner's
dog, back when Heidi (Eric Cooper, and Bill Joy) were all grad students
at U.C. Berkeley and the early versions of BSD were being developed.
Biff was popular among the residents of Evans Hall, and was known
for barking at the mailman, hence the name of the command.
rc
- rc (as in ".cshrc" or "/etc/rc") = "RunCom"
"rc" derives from "runcom", from the
MIT CTSS system, ca. 1965.
There was a facility
that would execute a bunch of commands stored in a file; it was
called "runcom" for "run commands", and the file began to be called
"a runcom."
"rc" is also the name of the shell from
the new Plan 9 operating system.
- How do I ``undelete'' a file?
Someday, you are going to accidentally type
something like 'rm * .foo', and find you just deleted "*" instead of
"*.foo". Consider it a rite of passage.
For all intents and purposes, when you delete
a file with "rm" it is gone. Once you "rm" a file, the system totally
forgets which blocks scattered around the disk comprised your file.
Even worse, the blocks from the file you just deleted are going to be
the first ones taken and scribbled upon when the system needs more disk
space. However, never say never. It is theoretically possible if
you shut down the system immediately after the "rm" to recover portions
of the data. However, you had better have a very wizardly type person
at hand with hours or days to spare to get it all back.
Your first reaction when you "rm" a file by mistake
is why not make a shell alias or procedure which changes "rm" to move
files into a trash bin rather than delete them? That way you can recover
them if you make a mistake, and periodically clean out your trash bin.
Two points: first, this is generally accepted as a bad
idea. You will become dependent upon this behaviour of "rm", and you
will find yourself someday on a normal system where "rm" is really "rm",
and you will get yourself in trouble. Second, you will eventually find
that the hassle of dealing with the disk space and time involved in
maintaining the trash bin, it might be easier just to be a bit more
careful with "rm". For starters, you should look up the "-i" option
to "rm" in your manual.
- How can a
process detect if it's running in the background?
First of all: do you want to know if you're
running in the background, or if you're running interactively? If you're
deciding whether or not you should print prompts and the like, that's
probably a better criterion.
In general, you can't tell if you're running in
the background. The fundamental problem is that different shells and
different versions of UNIX have different notions of what "foreground"
and "background" mean - and on the most common type of system with a
better-defined notion of what they mean, programs can be moved arbitrarily
between foreground and background!
Shells that support job control, on UNIX systems
that support job control, put a process into the background by giving
it a process group ID different from the process group to which the
terminal belongs. They move it back into the foreground by setting the
terminal's process group ID to that of the process. Shells that do *not*
support job control, on UNIX systems that support job control, typically
do what shells do on systems that don't support job control.
- How can an
executing program determine its own pathname?
Your program can look at argv[0];
if it begins with a "/", it is probably the absolute pathname to your
program, otherwise your program can look at every directory named in the
environment variable PATH and try to find the first one that contains
an executable file whose name matches your program's argv[0] (which by
convention is the name of the file being executed). By concatenating that
directory and the value of argv[0] you'd probably have the right name.
- How do I
tell inside .cshrc if I'm a login shell?
When people ask this, they usually mean either:
How can I tell if it's an interactive shell?
or
How can I tell if it's a top-level shell?
You could perhaps determine if your shell truly
is a login shell (i.e. is going to source ".login" after it is done with
".cshrc") by fooling around with "ps" and "$$". Login shells generally
have names that begin with a '-'. If you're really interested in the other
two questions, here's one way you can organize your .cshrc to find out.
if (! $?CSHLEVEL) then # # This is a
"top-level" shell, # perhaps a login shell, perhaps a shell started
up by # 'rsh machine some-command' # This is where we should set PATH
and anything else we # want to apply to every one of our shells. # setenv
CSHLEVEL 0 set home = ~username # just to be sure source ~/.env # environment
stuff we always want else # # This shell is a child of one of our other
shells so # we don't need to set all the environment variables again.
# set tmp = $CSHLEVEL @ tmp++ setenv CSHLEVEL $tmp endif # Exit from
.cshrc if not interactive, e.g. under rsh if (! $?prompt) exit # Here
we could set the prompt or aliases that would be useful # for interactive
shells only. source ~/.aliases
- How do I use
popen(3) to open a process for reading AND writing?
The problem with trying to pipe both input and output to an arbitrary
slave process is that deadlock can occur, if both processes are waiting
for not-yet-generated input at the same time. Deadlock can be avoided
only by having BOTH sides follow a strict deadlock-free protocol, but
since that requires cooperation from the processes it is inappropriate
for a popen()-like library function.
The 'expect' distribution includes
a library of functions that a C programmer can call directly. One
of the functions does the rather than pipes, and has no deadlock problem.
It's portable to both BSD and SV. See the next answer for more about
'expect'.
The shell itself cannot interact with interactive
tty-based programs like these.
- How do I run
'passwd', 'ftp', 'telnet', 'tip' and other interactive programs from
a shell script or in the background?
The shell itself cannot interact with interactive
tty-based programs like these.
- How do I sleep()
in a C program for less than one second?
The first thing you need to be aware of is
that all you can specify is a MINIMUM amount of delay;
the actual delay will depend on scheduling issues such as system load,
and could be arbitrarily large if you're unlucky.
If you aren't calling it in a tight loop, then
you almost certainly aren't making microsecond-resolution requests
anyway, in which case you don't care about microseconds. And if you
did, you wouldn't be using UNIX anyway because random system indigestion
(i.e., scheduling) can make mincemeat out of any timing code.
The following code is adapted from Doug Gwyn's
System V emulation support for 4BSD and exploits the 4BSD select()
system call. Doug originally called it nap(); you probably
want to call it usleep();
/*
usleep -- support routine for 4.2BSD system call emulations
last edit: 29-Oct-1984 D A Gwyn
*/
extern int select();
int
usleep( usec ) /* returns 0 if ok, else -1 */
long usec; /* delay in microseconds */
{
static struct /* `timeval' */
{
long tv_sec; /* seconds */
long tv_usec; /* microsecs */
} delay; /* _select() timeout */
delay.tv_sec = usec / 1000000L;
delay.tv_usec = usec % 1000000L;
return select( 0, (long *)0, (long *)0, (long *)0, &delay );
}
- What's wrong
with having '.' in your $PATH ?
A bit of background: the PATH environment variable is a list of directories
separated by colons. When you type a command name without giving an
explicit path (e.g. you type 'ls', rather than '/bin/ls')
your shell searches each directory in the PATH list in order, looking
for an executable file by that name, and the shell will run the first
matching program it finds.
One of the directories in the PATH list can
be the current directory "." . It is also permissible to use an empty
directory name in the PATH list to indicate the current directory.
Both of these are equivalent.
Consider what happens in the case where "."
is the first entry in the PATH. Suppose your current directory is
a publically-writable one, such as "/tmp". If there just happens to
be a program named "/tmp/ls" left there by some other user, and you
type "ls" (intending, of course, to run the normal "/bin/ls" program),
your shell will instead run "./ls", the other user's program. Needless
to say, the results of running an unknown program like this might
surprise you.
It's slightly better to have "." at the end
of the PATH:
Now if you're in /tmp and you type "ls", the
shell will search /usr/ucb, /bin and /usr/bin for a program named
"ls" before it gets around to looking in ".", and there is less risk
of inadvertently running some other user's "ls" program. This isn't
100% secure though - if you're a clumsy typist and some day type "sl
-l" instead of "ls -l", you run the risk of running "./sl", if there
is one. Some "clever" programmer could anticipate common typing mistakes
and leave programs by those names scattered throughout public directories.
Beware.
Many seasoned Unix users get by just fine without
having "." in the PATH at all: If you do this, you'll need to type
"./program" instead of "program" to run programs in the current directory,
but the increase in security is probably worth it.
- Is it possible to reconnect
a process to a terminal after it has been disconnected, e.g. after starting
a program in the background and logging out?
Most variants of Unix do not support detaching
and attaching processes, as operating systems such as VMS and
Multics support.
|
|