I think you're confusing a shell
(a command line interpreter) with a terminal emulator.
A shell, when run interactively and pine
require a terminal or terminal emulator to interact with the user. pine
has nothing to do with the shell though.
A terminal in the older days was a device with a monitor and keyboard connected to a computer over a serial line to interact with the computer (which itself had no monitor or keyboard). The interface is simple and text based.
The serial line on the computer is a character device file (something like /dev/ttyS0
on Linux for instance). Applications that interact with the terminal write data to that device for display on the terminal.
For instance, in the simplest case, pine
writing ASCII a
to /dev/ttyS0
would cause the sequence of bits corresponding to that a
character to be sent over the serial line, and the terminal displays a a
on the screen at the current cursor position.
And when the user presses a
on the keyboard, in the simplest case, the terminal sends that same sequence of bits on the other wire that goes to the computer and the system puts the a
character on a buffer, and when pine
does a read()
on /dev/ttyS0
, it returns that a
character.
Terminals have evolved from a things like tele-typewriters (no screen, the a
was printed on paper) to ones with CRT monitors, then some with more an more capabilities like cursor positioning, region clearing/scrolling, colour support all of which pine
uses, or even graphical capabilities. X later provided with a much more advanced way to interact with a computer this time over a network instead of serial line and windowing capabilities and this time using a much more complex protocol than just a sequence of characters to be sent and a few escape sequences.
Still, decades of applications had been written for the terminal. There are a lot of things that can be done with the terminal that can't be done with X. Because the data is just two streams of characters going in both directions, it's easy for instance to export a terminal session over the network (think telnet, ssh), and an application like cat
can be used to write to a terminal to display the content of a file for the user to view on his screen and can be used the exact same way, unmodified for that same content to be stored in a file or sent over the network to some server... (all is needed is redirect where that output goes). The same kind of thing can't be done with X applications that generally have one usage and can't cooperate with each other easily.
For those reasons and more, terminals have always been in use even long after X was wild-spread.
Only, now, instead of having real terminals, we have terminal emulators like xterm
, gnome-terminal
, eterm
... Those emulate a terminal but are just themselves X applications (that run on the computer and are displayed on a X server, on the same computer or another).
By default, when you start such a terminal emulator application, a shell is started in them, which is why there's sometimes confusion between the two. You don't have to run a shell in a terminal emulator, pine
doesn't have to be started by a shell, but it does require a terminal. It is a semi-graphic terminal application. It interacts with a terminal device, and at the other end of that device, it expects a terminal or terminal emulator with a minimal set of capabilities like cursor positioning, standout character highlighting...
The 2 approaches I see here are more:
- setting a inline section or a POD-like documentation to display as help, or
- properly defining a
.man
file to add to your local man
structure
I honestly don't see the point of having a separate file for that kind of help, unless you have a very big tool and the interface/GUI is already in different file(s).
So stay "plain and simple": all in one file regarding your command-line frontend.
You can still organize it as a chunk of inline-text or properly defined function which sole purpose is to display the help. So no ill done to the poor guy who will maintain your script in 10 years.
Best Answer
First, note that
$@
without quotes makes no sense and should not be used.$@
should only be used quoted ("$@"
) and in list contexts.for i in "$@"
qualifies as a list context, but here, to loop over the positional parameters, the canonical, most portable and simpler form is:Now, to loop over the elements starting from the second one, the canonical and most portable way is to use
shift
:After
shift
, what used to be$1
has been removed from the list (but we've saved it in$first_arg
) and what used to be in$2
is now in$1
. The positional parameters have been shifted1
position to the left (useshift 2
to shift by 2...). So basically, our loop is looping from what used to be the second argument to the last.With
bash
(andzsh
andksh93
, but that's it), an alternative is to do:But note that it's not standard
sh
syntax so should not be used in a script that starts with#! /bin/sh -
.In
zsh
oryash
, you can also do:to loop from the 3rd to the 3rd last argument.
In
zsh
,$@
is also known as the$argv
array. So to pop elements from the beginning or end of the arrays, you can also do:(
shift
can also be written1=()
inzsh
)In
bash
, you can only assign to the$@
elements with theset
builtin, so to pop 3 elements off the end, that would be something like:And to loop from the 3rd to the 3rd last:
POSIXly, to pop the last 3 elements of
"$@"
, you'd need to use a loop: