[疑惑]在shell里输入$0会发生什么

这是我在靶场里发现的一个问题, 在最开始的shell中

steiner@nesteiner:~$ $0

Command '-bash' not found, did you mean:

  command 'rbash' from deb bash
  command 'bash' from deb bash

Try: sudo apt install <deb name>

换成zsh

steiner@nesteiner:~$ zsh
(base) ➜  ~ $0    
(base) ➜  ~ exit
(base) ➜  ~ exit
steiner@nesteiner:~$ 

image

$加变量名字是使用, $0的解释可以看这里。 然后为啥bash的$0的值是-bash我就不知道了。zsh的$0的值是zsh。所以可以直接执行

${0} 就当 c语言里面的 argv[0]就行

懵啥?

为什么不直接试试 echo $0 或者 set -x 呢?

是不是有什么插件?

这个不是 login 么。。以 login 方式登录shell的时候 $0 = -shell 非 login 就是 $0 = shell

Difference between Login Shell and Non-Login Shell?


A login shell is one whose first character of argument zero is a -, or one started with the --login option.

1赞

知识点有点偏,当初没学到 :joy:

调用 Shell 的程序可以随意设置参数表 ARGV,比如把 Bash 的 $0 改成 -hello

~ $ echo $0
-zsh
~ $ cat tmp.c
#include <unistd.h>
int
main(void)
{
    execlp("bash", "-hello", NULL);
}
~ $ cc tmp.c
~ $ ./a.out
~ $ echo $0
-hello
~ $

但是我不确定 iTerm 和 Terminal 究竟是怎么做的,它们或许不像上面,或许是用 login(1) 实现的?因为我每次打开终端都会输出一行:

Last login: Thu May 14 20:15:30 on ttys001

tty 登录的话也会有 Last login 相关的提示, 这个好像和 lastlog 有关.

terminal 的话应该也是能指定默认的 shell 启动命令, konsole就有相关的设置

嗯,终端应该就是通过 login(1) 启动 Shell 的,比如:

login -f username /path/to/app arg1 arg2

然后 login 会把 app 改成 -app 当作 argv[0]

~ $ cat tmp.c
#include <stdio.h>
int
main(int argc, const char* argv[])
{
    printf("%s\n", argv[0]);
}
~ $ cc tmp.c
~ $ login -f xcy ./a.out
-a.out
~ $
1赞