2015年10月13日 星期二

[Linux 常見問題] Bash - What is $* and $# in Linux?

Source From Here 
Question 
What do the following environment variables in Linux mean? 
1. What is $* (dollar sign followed by an asterisk)?
2. What is $# (dollar sign next to a hash mark/number sign/octothorpe/pound sign)?

What-Is 
From here
  1. $#    Stores the number of command-line arguments that   
  2.       were passed to the shell program.  
  3. $?    Stores the exit value of the last command that was   
  4.       executed.  
  5. $0    Stores the first word of the entered command (the   
  6.       name of the shell program).  
  7. $*    Stores all the arguments that were entered on the  
  8.       command line ($1 $2 ...).  
  9. "$@"  Stores all the arguments that were entered  
  10.       on the command line, individually quoted ("$1" "$2" ...).  
So basically, $# is a number of arguments given when your script was executed. $* is a string containing all arguments. For example, $1 is the first argument and so on. This is useful, if you want to access a specific argument in your script. 

As Brian commented, here is a simple example. If you run following command: 
$ ./command -yes -no /home/username

The we will have: 
$# = 3
$* = -yes -no /home/username
$@ = array: {"-yes", "-no", "/home/username"}
$0 = ./command, $1 = -yes etc.

These are part of POSIX standard, and should be supported by all compliant shells. For the reference, below is POSIX standard definitions for each special parameter. Do note there's three additional variables: $-, $$ and $!. 
$- 
(Hyphen.) Expands to the current option flags (the single-letter option names concatenated into a string) as specified on invocation, by the set special built-in command, or implicitly by the shell.

$$ 
Expands to the decimal process ID of the invoked shell. In a subshell (see Shell Execution Environment ), '$' shall expand to the same value as that of the current shell.

$! 
Expands to the decimal process ID of the most recent background command (see Lists) executed from the current shell. (For example, background commands executed from subshells do not affect the value of "$!" in the current shell environment.) For a pipeline, the process ID is that of the last command in the pipeline.

Check sample bash script: 
- testSV.sh 
  1. #!/bin/bash  
  2. echo -e "\t[Info] \$#=$#"  
  3. echo -e "\t[Info] \$*='$*'"  
  4. echo -e "\t[Info] \$@ is an array. Below will loop input argument(s):"  
  5. for arg in $@  
  6. do  
  7.     echo -e "\t\t$arg"  
  8. done  
  9. echo -e "\t[Info] \$0=$0, \$1=$1 ..."  
  10. ls /notexist  
  11. echo -e "\t[Info] Exit with none zero - $? / $!"  
  12. ls /  
  13. echo -e "\t[Info] Exit with zero - $? / $!"  
  14. ps | grep "testSV.sh"  
  15. echo -e "\t[Info] Bash with PID=$$"  
  16. echo "$-"  
Execution sample: 
# ./testSV.sh yes no /home
[Info] $#=3
[Info] $*='yes no /home'
[Info] $@ is an array. Below will loop input argument(s):
yes
no
/home
[Info] $0=./testSV.sh, $1=yes ...
ls: cannot access /notexist: No such file or directory
[Info] Exit with none zero - 2 /
bin cdrom etc initrd.img lib lost+found mnt proc run srv tmp var vmlinuz.old
boot dev home initrd.img.old lib64 media opt root sbin sys usr vmlinuz
[Info] Exit with zero - 0 /
43935 pts/0 00:00:00 testSV.sh
[Info] Bash with PID=43935
hB

Supplement 
Bash - Internal Variables

沒有留言:

張貼留言

[Git 常見問題] error: The following untracked working tree files would be overwritten by merge

  Source From  Here 方案1: // x -----删除忽略文件已经对 git 来说不识别的文件 // d -----删除未被添加到 git 的路径中的文件 // f -----强制运行 #   git clean -d -fx 方案2: 今天在服务器上  gi...