I would like to ask that what is the meaning of $$ in a .sh script.
My program:
#!/bin/sh
V1=$1
V2=$2
V3=$$
echo "$V1 $V2 $V3"
Calling:
./mypro.sh 1 2 3
Output:
1 2 7215
$$ is the pid of the bash process.
From the bash man page section Special Parameters:
$ Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the current shell, not the subshell.
Related
The manual of (t)csh say:
exit [expr]
The shell exits either with the value of the specified expr (an expression, as described under Expressions) or,
without expr, with the value 0.
But if run tcsh -c 'exit 5; echo after exit'; echo $?, we get the following output (test on tcsh of ubuntu/centos and freebsd 10.3):
after exit
0
It seems like the exit command is skipped. How to get the same action like the POSIX/bash shell?
What are you trying to do in a POSIX shell? If you want to print something and exit normally just do printf "%s\n" 'my message'; exit 0. (See https://unix.stackexchange.com/questions/65803/why-is-printf-better-than-echo for reasons not to use echo)
This is probably a bug in csh that's kept in tcsh for backwards compatibility reasons.
(t)csh is line-oriented in a way that other shells are not and generally processes input a line at a time, for instance
This script:
#!/bin/tcsh -f
exit 5
echo 'after exit'
exits with status 5 when executed.
This script, on the other hand, prints after exit.
#!/bin/tcsh -f
exit 5; echo 'after exit'
Somewhat more surprisingly, a string containing a newline passed to /bin/tcsh is treated like the single-line script, not the multi-line one.
% perl -e 'system("/bin/tcsh -f -c \"exit 5\necho after\"")'
This question already has answers here:
$$ in a script vs $$ in a subshell
(4 answers)
Closed 7 years ago.
In my shell scripts,I wrote those:
#! /bin/bash
(ls;echo$$)
echo$$
then I run the shell,the two output is the same
2592
2592
why subshell didn't have a new process id?
$$ is the process ID of the main shell. To get the process ID of a subshell, use BASHPID:
$ echo $$ $BASHPID; ( echo $$ $BASHPID; )
19610 19610
19610 21937
The subshell has PID 21937.
Documentation
From man bash:
BASHPID
Expands to the process ID of the current bash process. This differs from $$ under certain circumstances, such as sub‐
shells that do not require bash to be re-initialized.
By contrast, $$ is documented as follows:
$$
Expands to the process ID of the shell. In a () subshell, it expands
to the process ID of the current shell, not the sub‐ shell.
I do not know what the return value means
grep abc Letters
echo $?
0
echo $0
gives "-bash"
what does "-bash" return value mean
The question should be moved into https://unix.stackexchange.com/.
But anyway, $0 is the value of the variable that holds the name of an application that's executing the command. It's like argv[0] in C.
Example:
cdshines#v3700:~|⇒ echo $0 # I'm in zsh now
/bin/zsh
cdshines#v3700:~|⇒ bash # let's run bash:
cdshines#v3700:~$ echo $0
bash
cdshines#v3700:~$ sh # we need to go deeper:
$ echo $0
sh
$ zsh # deeper!
cdshines#v3700:~|⇒ echo $0
zsh
cdshines#v3700:~|⇒ # hit Ctrl-D (pop one level):
$ echo $0
sh
$ # pop again:
cdshines#v3700:~$ echo $0
bash
cdshines#v3700:~$ exit # again:
cdshines#v3700:~|⇒ echo $0
/bin/zsh # we're at the starting point now
The meaning of $0 is explained in the Bash manual (here, near the bottom of the page):
Expands to the name of the shell or shell script. This is set at shell
initialization. If Bash is invoked with a file of commands (see Shell
Scripts), $0 is set to the name of that file. If Bash is started with
the -c option (see Invoking Bash), then $0 is set to the first
argument after the string to be executed, if one is present.
Otherwise, it is set to the filename used to invoke Bash, as given by
argument zero.
(Unfortunately, it's difficult to search for $0 in the bash manual, since it's listed as just 0.)
By convention, if the current bash process is a login shell, $0 (argv[0] in C terms) is modified, either by bash itself or by the login process, adding a - character to the beginning.
On some systems, /bin/sh is a symbolic link to /bin/bash. If so, and if bash is invoked via the /bin/sh symlink, then $0 will be sh or -sh.
$?, also explained in the Bash manual, "Expands to the exit status of the most recently executed foreground pipeline". More simply, it's the status of the most recently executed command (in your case, grep abc Letters), typically 0 if that command succeeded, or some non-zero value (often, but not always, 1) if it failed.
Return status of the latest shell command is represented by $?:
date
echo $?
0
Here 0 means successful return from previously completed command(date) and any non-zero value means failure status.
When you access $0 is is actually name of the executable in shell and in your case it is -bash since you're running it on the shell.
Please explain this problem with incrementing value, we have next file named test.sh
#!/bin/bash
ps aux | grep test.sh -c
echo $(ps aux | grep test.sh -c)
and then run it
$ ./test.sh
2
3
I know there is two lines after grep slice (1 with test.sh, 2 with grep), why 3 come in? Thanks
You get 3 in the second case because the second command $(...) (i.e. command substitution) executes in a subshell.
From the manual:
Command substitution, commands grouped with parentheses, and
asynchronous commands are invoked in a subshell environment that is a
duplicate of the shell environment, ...
$ bash -c 'echo "0 is $0 1 is $1"' abc def
0 is abc 1 is def
$ echo 'echo "0 is $0 1 is $1"' > bashtest
$ bash bashtest abc def
0 is bashtest 1 is abc
The second run is equivalent to if I turned bash test into a shellscript with the shebang and then ran it directly...
Basically I'm wondering why abc isn't always $1. It becomes $0 when run with bash -c.
I also didn't know this. But the man page mentions it:
-c string: If the -c option is present, then commands are read from
string. If there are arguments after the string, they are
assigned to the positional parameters, starting with $0.
The ARGUMENTS section has an even more detailed explanation:
ARGUMENTS
If arguments remain after option processing, and neither the -c nor the
-s option has been supplied, the first argument is assumed to be the
name of a file containing shell commands. If bash is invoked in this
fashion, $0 is set to the name of the file, and the positional parame‐
ters are set to the remaining arguments. Bash reads and executes com‐
mands from this file, then exits. Bash's exit status is the exit sta‐
tus of the last command executed in the script. If no commands are
executed, the exit status is 0. An attempt is first made to open the
file in the current directory, and, if no file is found, then the shell
searches the directories in PATH for the script.