JustBash.Commands.StdinOperand (JustBash v0.4.0)

View Source

The - file operand.

POSIX gives every utility that takes a file operand the same reading of a bare -: it names standard input, not a file called -. Resolving it as a path instead reaches the filesystem, where it does not exist — harmless while the read paths failed silently, and a hard error the moment #70 taught them to report the read they could not do.

sort -, uniq - and grep pat - are the shapes that matter: they are how a pipeline names its own input when it also wants to name a file, and under set -o pipefail a diagnostic there kills the pipeline.

Summary

Functions

Drop the first -- and keep every other argument, including ones that look like flags.

Split a command's arguments into its file operands, honouring --.

Read a file operand, taking - as stdin rather than resolving it as a path. Mirrors JustBash.FS.read_file/2, so the error arm a caller already has for a real path keeps working unchanged.

Split args at the first --.

True when a file operand names standard input rather than a path.

Functions

drop_end_of_options(args)

@spec drop_end_of_options([String.t()]) :: [String.t()]

Drop the first -- and keep every other argument, including ones that look like flags.

For a command that does not parse options, arguments on either side of -- are operands. Concatenating them is the POSIX reading of -- as a marker rather than a filename. After --, a second -- stays an operand.

operands(args)

@spec operands([String.t()]) :: [String.t()]

Split a command's arguments into its file operands, honouring --.

Enum.reject(args, &String.starts_with?(&1, "-")) is not that split. It deletes -, which is an operand naming stdin and never an option, and it deletes every operand after --, which is the only way to name a file whose name begins with a dash. Both deletions are silent: the command reads one fewer input than it was given and still exits 0.

read(fs, cwd, operand, stdin)

@spec read(JustBash.FS.t(), String.t(), String.t(), String.t() | nil) ::
  {:ok, binary(), JustBash.FS.t()} | {:error, VFS.Error.t()}

Read a file operand, taking - as stdin rather than resolving it as a path. Mirrors JustBash.FS.read_file/2, so the error arm a caller already has for a real path keeps working unchanged.

split_end_of_options(args)

@spec split_end_of_options([String.t()]) :: {[String.t()], [String.t()]}

Split args at the first --.

Returns {before, extra} where extra is everything after -- and must not be parsed as options. A second -- is an operand named --. When -- is absent, extra is [] and before is args.

Hand-rolled parsers call this once at their entry point, parse flags from before, and append extra as file operands — the same -- stop FlagParser and operands/1 already implement:

{option_args, extra} = StdinOperand.split_end_of_options(args)
with {:ok, opts} <- parse_flags(option_args, defaults) do
  {:ok, %{opts | files: opts.files ++ extra}}
end

stdin?(arg1)

@spec stdin?(String.t()) :: boolean()

True when a file operand names standard input rather than a path.