= Bash Test = for portable `sh(1)`, see [[Shell/Test|here]]. <> ---- == Usage == There are three interfaces to shell tests: * `test(1)` * the alias `[` (which requires a `]` following all operands, strings, and expressions) * the grammar `[[ TEST ]]` The first two are equivalent, POSIX compliant, and portable. `test(1)` sets the exit code to 0 if the test is true, and 1 if false. The third is an enhancement of `ksh(1)` that was included in multiple downstream shells, including `bash(1)`. [[Bash/Expansion#Word_Splitting|Word splitting]] and [[Bash/Expansion#Filename_Expansion|globbing]] are disabled within this grammar, preempting many subtle bugs. Shell tests are frequently used with [[Bash/Logic#Conditional_Logic|conditional logic]]. {{{ if [[ TEST ]]; then : fi }}} ---- == Variable Tests == || '''Usage''' || '''True if...''' || || `var1 = var2` || var1 is equivalent to var2 || || `var1 != var2` || var1 is not equivalent to var2 || || `-z var` || string length of var is 0 || || `-n var` || string length of var is not 0 || || `-v var` || var is set || || `var1 -eq var2` || var1 is numerically equal to var2 || || `var1 -ne var2` || var1 is numerically inequal to var2 || || `var1 -gt var2` || var1 is numerically greater than var2 || || `var1 -ge var2` || var1 is numerically greater than/ equal to to var2 || || `var1 -lt var2` || var1 is numerically lesser than var2 || || `var1 -le var2` || var1 is numerically lesser than/ equal to to var2 || === Patterns === To match a variable against a pattern, try: {{{ if [[ $var = a* ]]; then echo "var starts with an 'a'" fi }}} To match a variable against a regular expression, try: {{{ if [[ $var =~ ^[^a] ]]; then echo "var does not start with an 'a'" fi }}} ---- == File Tests == These are probably what you are looking for. || '''Usage''' || '''True if...''' || || `-d fn` || directory exists || || `-e fn` || file exists || These rarely are useful. || '''Usage''' || '''True if...''' || || `-b fn` || file exists and is a block special file || || `-c fn` || file exists and is a character special file || || `-f fn` || file exists and is a regular file || || `-g fn` || file exists and its set-group-id bit is set || || `-h fn` || '''symbolic link''' exists (same as `-L`) || || `-p fn` || '''named pipe''' (FIFO) exists || || `-r fn` || file exists and is readable || || `-s fn` || file exists and its size is greater than zero || || `-t fn` || '''file descriptor''' is open and refers to a terminal || || `-u fn` || file exists and its set-user-id bit is set || || `-w fn` || file exists and is writable || || `-x fn` || file exists and is executable || || `-L fn` || '''symbolic link''' exists (same as `-h`) || || `-S fn` || '''socket''' exists || || `fn1 -ef fn2` || fn1 has same device and inode numbers as fn2 || || `fn1 -nt fn2` || fn1 is newer (modification date) than fn2 || || `fn1 -ot fn2` || fn1 is older (modification date) than fn2 || ---- == Compound Logic == `bash(1)` greatly simplifies compound logic constructs as compared to `sh(1)`. To negate a test, insert `!` before the expression. Note that negation is applied to the '''last''' test only. {{{ if [[ ! TEST ]]; then : fi }}} The `AND` and `OR` operators can be used within ''or'' between `[[` calls. {{{ if [[ TEST && TEST ]] && [[ TEST ]]; then : fi if [[ TEST || TEST ]] || [[ TEST ]]; then : fi }}} Use parentheses for ordering operations. {{{ if [[ TEST && ( TEST || TEST ) ]]; then : fi }}} Note that `[[` is capable of [[Bash/Logic#Conditional_Logic|short circuiting]]. ---- CategoryRicottone