$( ): put a command's output inside another command
Bash runs the command inside $( ) first and puts its output in its place:
echo "I am $(whoami) on $(hostname)"
echo "/etc has $(ls /etc | wc -l) entries"In the terminal
student@vulntech:~$ echo "I am $(whoami) on $(hostname)" I am student on vulntech student@vulntech:~$ echo "/etc has $(ls /etc | wc -l) entries" /etc has 64 entries
It's often used with variables. date +%F prints today's date as year-month-day, perfect for naming backups:
today=$(date +%F)
mkdir "backup-$today"
lsIn the terminal
student@vulntech:~$ today=$(date +%F) student@vulntech:~$ mkdir "backup-$today" student@vulntech:~$ ls backup-2026-10-17
Tip: Old scripts use backticks for the same thing:
`date`.$( )is easier to read and can be nested.
Exit status: did it work?
Every command finishes with an exit status: 0 means success, anything else means something went wrong. $? holds the status of the last command:
ls /etc/hostname
echo $?
ls /etc/nothing-here
echo $?In the terminal
student@vulntech:~$ ls /etc/hostname /etc/hostname student@vulntech:~$ echo $? 0 student@vulntech:~$ ls /etc/nothing-here ls: cannot access '/etc/nothing-here': No such file or directory student@vulntech:~$ echo $? 2
Running several commands
| You type | The second command runs |
|---|---|
a ; b | Always, after a finishes |
a && b | Only if a worked (exit status 0) |
a || b | Only if a failed |
mkdir projects && cd projects && pwd
cd /etc/nothing-here || echo "No such folder, staying here"In the terminal
student@vulntech:~$ mkdir projects && cd projects && pwd /home/student/projects student@vulntech:~/projects$ cd /etc/nothing-here || echo "No such folder, staying here" -bash: cd: /etc/nothing-here: No such file or directory No such folder, staying here
Think of it like this: Read
&&as and then and||as or else: make the folder and then go in; go there, or else complain.
Common mistake: Use
&&when the next command depends on the last one. If the folder doesn't exist,cd old-logs && rm *.logdeletes nothing, butcd old-logs ; rm *.logdeletes the logs in whatever folder you're still in!
Remember:
$(command)inserts the output.&&= only if it worked,||= only if it failed,$?= the last exit status.