Scripts turn a sequence of commands you keep retyping into a reusable tool.
A script is a text file of commands. Its first line, the shebang, tells the kernel which interpreter to use: #!/usr/bin/env bash finds bash on the PATH and is the most portable choice. Make the file executable once with chmod +x script.sh, then run it as ./script.sh. The ./ is needed because the current directory is not on PATH. Alternatively bash script.sh runs it without the execute bit (and ignores the shebang).
Arguments arrive as positional parameters:
$1,$2, ... the arguments; use${10}from the tenth on,$#the number of arguments,$0the name the script was called by,"$@"all arguments, each kept as a separate word: the right way to pass them on.
${2:-Hello} means "the second argument, or Hello if it is missing or empty"; you will see more of these expansions later. A script runs in a new process, so cd or variables set inside it do not affect your terminal; use source script.sh when you actually want that.
Name scripts clearly, keep a usage comment at the top, and exit with a non-zero status on errors.
Example
cd "$(mktemp -d)"
cat > greet.sh <<'EOF'
#!/usr/bin/env bash
# usage: greet.sh NAME [GREETING]
name=$1
greeting=${2:-Hello}
echo "$greeting, $name! ($# args, called as $0)"
EOF
chmod +x greet.sh
./greet.sh Ada # Hello, Ada! (1 args, called as ./greet.sh)
./greet.sh Bob "Hi there" # Hi there, Bob! (2 args, called as ./greet.sh)
bash greet.sh Cy # Hello, Cy! (1 args, called as greet.sh)Remember
- Start with #!/usr/bin/env bash and chmod +x the file
- $1..$9, ${10}, $# and "$@" give you the arguments
- A script runs in a child process; source it to affect the current shell
Watch out for
- Running
script.shwithout ./ and getting 'command not found' because . is not on PATH.