UNIX — универсальная среда программирования - Брайан Керниган
Шрифт:
Интервал:
Закладка:
#include "system.c"
3.5.58 vis1.c
/* vis: make funny characters visible (version 1) */
#include <stdio.h>
#include <ctype.h>
main() {
int c;
while ((c = getchar()) != EOF)
if (isascii(c) &&
(isprint(c) || c=='n' || c=='t' || c==' '))
putchar(c);
else
printf("\%03o", c);
exit(0);
}
3.5.59 vis2.c
/* vis: make funny characters visible (version 2) */
#include <stdio.h>
#include <ctype.h>
main(argc, argv)
int argc;
char *argv[];
{
int с, strip = 0;
if (argc > 1 && strcmp(argv[1] , "-s") == 0)
strip = 1;
while ((c = getchar()) != EOF) if (isascii(c) &&
(isprint(c) || c=='n' || c=='t' || c==' '))
putchar(c);
else if (!strip)
printf("\%03o", c);
exit(0);
}
3.8.60 vis3.c
/* vis: make funny characters visible (version 3) */
#include <stdio.h>
#include <ctype.h>
int strip = 0; /* 1 => discard special characters */
main(argc, argv)
int argc;
char *argv[];
{
int i;
FILE *fp;
while (argc > 1 && argv[1][0] == '-') {
switch (argv[1][1]) {
case 's': /* -s: strip funny chars */
strip = 1;
break;
default:
fprintf(stderr, "%s: unknown arg %sn",
argv[0], argv[1]);
exit(1);
}
argc--;
argv++;
}
if (argc == 1)
vis(stdin);
for (i = 1; i < argc; i++)
if ((fp=fopen(argv[i], "r")) == NULL) {
fprintf(stderr, "%s: can't open %sn",
argv[0], argv[i]);
exit(1);
} else {
vis(fp);
fclose(fp);
}
exit(0);
}
vis(fp) /* make chars visible in FILE *fp */
FILE *fp;
{
int c;
while ((c = getc(fp)) != EOF)
if (isascii(c) &&
(isprint(c) || c=='n' || c=='t' || c==' '))
putchar(c);
else if (!strip)
printf("\%03o", с);
}
3.8.61 waitfile.c
/* waitfile: wait until file stops changing */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
char *progname;
main(argc, argv)
int argc;
char *argv[];
{
int fd;
struct stat stbuf;
time_t old_time = 0;
progname = argv[0];
if (argc < 2)
error("Usage: %s filename [cmd]", progname);
if ((fd = open(argv[1], 0)) == -1)
error("can't open %s", argv[1]);
fstat(fd, &stbuf);
while (stbuf.st_mtime != old_time) {
old_time = stbuf.st_mtime;
sleep(60);
fstat(fd, &stbuf);
}
if (argc == 2) { /* copy file */
execlp("cat", "cat", argv[1], (char*)0);
error("can't execute cat %s", argv[1]);
} else { /* run process */
execvp(argv[2], &argv[2]);
error("can't execute %s", argv[2]);
}
exit(0);
}
#include "error.c"
3.8.62 watchfor
# watchfor: watch for someone to log in
PATH=/bin:/usr/bin
case $# in
0) echo 'Usage: watchfor person' 1>&2; exit 1
esac
until who | egrep "$1"
do
sleep 60
done
3.8.63 watchwho
# watchwho: watch who logs in and out
PATH=/bin:/usr/bin
new=/tmp/wwho1.$$
old=/tmp/wwho2.$$
> $old # create an empty file
while : # loop forever
do
who >$new
diff $old $new
mv $new $old
sleep 60
done | awk '/>/ { $1 = "in: "; print }
/</ { $1 = "out: "; print }'
3.8.64 which1
# which cmd: which cmd in PATH is executed, version 1
case $# in
0) echo 'Usage: which command' 1>&2; exit 2
esac
for i in `echo $PATH | sed 's/^:/.:/
s/::/:.:/g
s/:$/:./
s/:/ /g'`
do
if test -f $i/$1 # use test -x if you can
then
echo $i/$1
exit 0 # found it
fi
done
exit 1 # not found
3.8.65 which1.H
# which cmd: which cmd in PATH is executed, version 1
case $# in
0) echo 'Usage: which command' 1>&2; exit 2
esac
for i in `echo $PATH | sed 's/^:/.:/
s/::/:.:/g
s/:$/:./
s/:/ /g'`
do
if test -f $i/$1 # use test -x if you can
then
echo $i/$1
exit 0 # found it
fi
done
exit 1 # not found
@@@ Fri Oct 14 14:21:11 EDT 1983 original version
3.8.66 which2
# which cmd: which cmd in PATH is executed, final version
opath=$PATH PATH=/bin:/usr/bin
case $# in
0) echo 'Usage: which command' 1>&2; exit 2
esac
for i in `echo $opath | sed 's/^:/.:/
s/::/:.:/g
s/:$/:./
s/:/ /g'`
do
if test -f $i/$1 # this is /bin/test
then # or /usr/bin/test only
echo $i/$1
exit 0 # found it
fi
done
exit 1 # not found
3.8.67 wordfreq
awk ' { for (i = 1; i <= NF; i++) num[$i]++ }
END {for (word in num) print word, num[word] }
' $*
3.8.68 zap1
# zap pattern: kill all processes matching pattern
# BUG in this version
PATH=/bin:/usr/bin
case $# in
0) echo 'Usage: zap pattern' 1>&2; exit 1
esac
kill `pick `ps -ag | grep "$*"` | awk '{print $1}'`
3.8.69 zap2
# zap pat: kill all processes matching pat
# final version
PATH=/bin:/usr/bin
IFS='
' # just a newline
case $1 in
"") echo 'Usage: zap [-2] pattern' 1>&2; exit 1 ;;
-*) SIG=$1; shift
esac
echo ' PID TTY TIME CMD'
kill $SIG `pick `ps -ag | egrep "$*"|` | awk '{print $1}'`
3.8.70 zap.c
/* zap: interactive process killer */
#include <stdio.h>
#include <signal.h>
char *progname; /* program name for error message */
char *ps = "ps -ag"; /* system dependent */
main(argc, argv)
int argc;
char *argv[];
{
FILE *fin, *popen();
char buf[BUFSIZ];
int pid;
progname = argv[0];
if ((fin = popen(ps, "r")) == NULL) {
fprintf (stderr, "%s: can't run %sn", progname, ps);
exit(1);
}
fgets(buf, sizeof buf, fin); /* get header line */
fprintf (stderr, "%s", buf);
while (fgets(buf, sizeof buf, fin) != NULL)
if (argc == 1 || strindex(buf, argv[1]) >= 0) {
buf[strlen(buf)-1] = ' '; /* suppress n */
fprintf (stderr, "%s? ", buf);
if (ttyin() == 'y') {
sscanf(buf, "%d", &pid);
kill(pid, SIGKILL);
}
}
exit(0);
}
#include "ttyin2.c"
#include "strindex.c"
#include "efopen.c"
Примечания
1
Система UNIX представляет собой продукт BELL Laboratories. Слово "UNIX" не акроним: оно перекликается со словом "MULTICS" — названием операционной системы, с которой работали К. Томпсон и Д. Ритчи ранее.
2
В современных системах такого ограничения нет, длина файла там ограничена в большинстве случаев 255 символами (прим. редактора)
3
Порядок, конечно, не строго алфавитный, прописные буквы предшествуют строчным. Чтобы узнать порядок, используемый в программе sort, см. ascii(7).
4
Эта возможность плохо реализована в shell. Просмотр файла после ввода каждой команды сказывается на времени работы системы. Кроме того, если вы достаточно долго работаете в редакторе, то не узнаете о новой почте, поскольку не задаете новых команд в начальном интерпретаторе shell. Лучшим решением была бы проверка через каждые несколько минут, а не после очередной команды. В гл. 5 и 7 будет показано, как реализовать такую проверку получения почты. Третьим решением, хотя и не для всех доступным, может быть извещение, посылаемое самой программой mail, — она точно "знает", когда появится почта.