No, and it works because $1
is emptyusually [1] and not quoted. The resulting command from see foo
would be see foo
.
If you quoted it however as in:
alias see='nano --view "$1"'
It would become see <empty> foo
and you would open a new buffer in addition to foo
in nano
.
[1]
$1
is expanded to whatever the value of the shell's first positional parameter is - in an interactive shell that's usually nothing (since interactive shells aren't typically invoked with positional parameters), however there's nothing to stop it from being set to something arbitrary (for example with the set
shell builtin / help set
) - set -- foo bar; see baz
for example would open foo
then baz
. (Freely copied from comment by @steeldriver as it is an important note.)
So do not trust it is always empty.
You can also try:
$ alias e='echo @$1@'
$ e foo <-- would become: echo @$1@ foo
@@ foo
| |
| +--- foo is next string
+------ $1 is empty
Under the hood so to speak you would see something like:
execve("/bin/nano", ["nano", "--view", "foo"], 0xabc...)
and for the quoted version:
execve("/bin/nano", ["nano", "--view", "", "foo"], 0xabc...)
In the main function of nano
int main(int argc, char *argv[])
argc
, (argument count), would be 3 and 4 respectively and argv
, (argument vector / array), would be the strings in the square brackets.
You can use:
alias see='nano --view'
Then by issuing:
$ see foo
foo
will be $1
, (not really $1
but in comparison), and the command will expand to:
nano --view foo
If you need to restrict nano to only open $1
, (first argument), you would need a function because:
see foo bar
would expand to nano --view foo bar
Then you could use something like:
see() {
nano --view "$1"
}
Then you would discard any argument above $1
and when execve
is called it would always be:
execve("/bin/nano", ["nano", "--view", "filename"], 0xabc...)
where filename
is $1
in bash
. Nano would not see $1
, only the value. Bash takes care of that.
When one use a shell function the arguments are defined as positional parameters, $1
, $2
, $3
, …, and the function has access to these. An alias is not treated as a function hence it does not have access to these parameters / they do not exists.
Try:
alias p1='echo "$# $1 END"'
p2() { echo "$# $1 END"; }
Result:
$ p1 a b c
0 END a b c
$ p2 a b c
3 a END
In general, Bash manual states:
For almost every purpose, shell functions are preferred over aliases.
and
There is no mechanism for using arguments in the replacement text, as in csh. If arguments are needed, a shell function should be used (see Shell Functions).
For the shellcheck
write up, see the wiki for SC2142.
see file1.txt file2.txt
. If the positional argument is valid, nano would open only one file. If it isn't, both files would be opened. Inside nano, you can switch between files with Alt-Comma/Alt-Period (see https://stackoverflow.com/a/62092148). – Haxiel Jun 20 '21 at 02:47