There is no standard way to retrieve the list of configuration variables that are supported on a system. If you program for a given POSIX version, the list in that version of the POSIX specification is your reference list. On Linux, getconf -a
lists all available variable.
fpathconf
isn't specific to PATH. It's about variables that are related to files, which are the ones that may vary from file to file.
Regarding ARG_MAX
on Linux, the rationale for depending on the stack size is that the arguments end up on the stack, so there had better be enough room for them plus everything else that must fit. Most other implementations (including older versions of Linux) have a fixed size.
Most limits go together with resource availability, with different resources depending on the limit. For example, a process may be unable to open a file even if it has fewer than OPEN_MAX
files open, if the system is out of memory that can be used for the file-related data.
Linux is POSIX-compliant on this point by default, so I don't know where you're getting at.
If you use ulimit -s
to restrict the stack size to less than ARG_MAX
, you're making the system no longer compliant. A POSIX system can typically be made non-compliant in any number of ways, including PATH=/nowhere
(making all standard utilities unavailable) or rm -rf /
.
The value of ARG_MAX
in limits.h
provides a minimum that applications can rely on. A POSIX-compliant system is allowed to let execve
succeed even if the arguments exceed that size. The guarantee related to ARG_MAX
is that if the arguments fit in that size then execve
will not fail due E2BIG
.
If my goal is to write a script for POSIX compatible shells, scripts that I would begin with #!/bin/sh, how permissible is this [[
syntax.
Not at all. Many modern Linux-based systems use dash
as /bin/sh
by default, which is fully POSIX-compliant and no more, and so [[
will not work. This includes every recent Debian and Ubuntu release, and their derivatives, as well as many other distributions. Historically these systems commonly used Bash there instead, and deliberately switched to improve performance.
Many other systems, including most of the BSDs and most commercial Unices, don't support [[
either and never have: their sh
is POSIX-only, or its extensions don't include the [[
syntax. OpenBSD's sh
does support a version of [[
, which is slightly different than Bash's; I don't know of any others that do, although they may exist. Otherwise, it's only systems that use Bash as /bin/sh
(or less often zsh
, or even less often some others) where [[
will work in something declared to be a sh
script.
On the other hand, the large majority of systems have Bash installed in practice, and just making your script explicitly be run with bash
will suffice for all of them. Bash's sh
-emulation mode has always been broken anyway.
Since you're relying on Bash features, I can't see any reason at all you'd want to declare it as a sh
script: just say #!/bin/bash
and be done, using [[
as much as you want — or even better, to the total exclusion of [
. If you instead want maximum portability, use [
or test
and POSIX sh
1, and write carefully.
1Note that some of the commercial Unices have, or have had, non-POSIX sh
as /bin/sh
; to work uniformly on those you'll need to run the scripts with the full path to the system's POSIX sh
.
Best Answer
Note that POSIX find does support options like other commands, and
--
to mark the end of them like other commands. Those are-H
and-L
.The
-print
,-type
... are not options, they're sometimes called predicates. They are arguments whose order matters that appear after the file paths which themselves appear after the options. You've also got(
and!
. Together, they build an expression that is used to determine what files to find.find
is not the only one.[
(akatest
) andexpr
are other commands whose arguments are used to build an expression.Like
find
,[
has operators that start with-
and are more than one-letter (-gt
,-eq
...).Like
find
,test
has issues where those operators may be confused with operands.If
$file2
is!
, it's a problem withfind
. If it's=
, it's a problem with (some)[
.For all of
find
,test
andexpr
, using options to build the expression would not really have worked. Another option could have been to have one string evaluated as the expression likeawk
orsed
. like forDo:
But that means implementing a grammar parser in
find
. That also means potential quoting nightmare for the"x"
and command line above.Actually AT&T Research did come up with such a command: tw (tree walker), but even though it's now open source, I'm not aware that it is really used out of AT&T.