Each takes a numerical argument that specifies the limit in
units shown in the table.
(You may use an arithmetic expression for the limit;
ksh automatically evaluates the expression.)
You can also give the argument
"unlimited" (which may actually mean some physical limit),
or you can omit the argument, in which case
it prints the current limit.
ulimit -a prints the
limits (or "unlimited") for all types. You can only
specify one type of resource at a time.
If you don't specify any option, -f is assumed.
Some of these options depend on operating system capabilities
that don't exist in older Unix versions. In particular,
some older versions have a fixed limit of 20 file descriptors
per process (making -n irrelevant), and some don't
support virtual memory (making -v irrelevant).
The -d and -s options have to do with
dynamic memory allocation, i.e., memory for which
a process asks the operating system at runtime.
It's not necessary for casual users to limit these,
though software developers may want to do so
to prevent buggy programs from
trying to allocate endless amounts of memory due to
infinite loops.
The -v option is similar; it puts a limit on
all uses of memory. You don't need this
unless your system has severe memory constraints
or you want to limit process size to avoid thrashing.
The -t option is another possible guard against
infinite loops. On single-user systems, a program that is in an infinite
loop but isn't allocating memory, writing files, or using the network
is not particularly dangerous; it's better to leave this unlimited and
just let the user kill the offending program. However, on shared server
systems, such programs definitely degrade the overall environment.
The problem in that case is that it's difficult to know what limit to set:
there are important and legitimate uses for long-running programs.