Reputation: 524
I want to find the name of a file in a folder on my server and set it to a variable to use it later. The problem is when I run my backup script the file name changes each time to compensate for the date. So I cannot just hard code the file name and path.
For example I know where the file will be - /var/backups/"unknownfilename.sql"
backuppath="/var/backups/"
How can I set $backupfile to the file in $backuppath?
After researching I can only find where people echo out the filenames, they never end up storing them to a variable.
Upvotes: 3
Views: 16608
Reputation: 295855
For bash (#!/bin/bash
):
backuppath=/var/backups
sqlfiles=( "$backuppath"/*.sql )
[[ -e $sqlfiles ]] || { echo "Matched no files" >&2; exit 1; }
If you want to refer to the first match:
echo "The first match found was: $sqlfiles"
If you want to refer to all array contents:
echo "Found the following files:"
printf '- %q\n' "${sqlfiles[@]}"
For POSIX sh (#!/bin/sh
) instead:
backuppath=/var/backups
# wrap in a function to avoid overwriting the global $1, $2, etc.
find_files() {
set -- "$backuppath"/*.sql
[ -e "$1" ] || { echo "Matched no files" >&2; exit 1; }
[ "$#" -gt 1 ] && echo "WARNING: Matched $# files; only taking first" >&2
sqlfile=$1
}
find_files
Points of note:
"$backuppath"
) should be inside quotes; the glob expression (*.sql
) should not.[[ -e $sqlfiles ]]
in bash, [ -e "$1" ]
in the POSIX sh version) protects against default behavior when no matches exist, which will use the glob expression itself (/var/backups/*.sql
) as a result; when tested for existence, this won't be present unless a file exists with literally that name (which is to say, a name containing an asterisk)./bin/sh
: Arrays, and the extended ([[ ]]
) test operator. If you were to use the standard test command, it would be [ -e "$sqlfiles" ]
instead; if you were to operate in a shell without arrays, you might wrap this logic in a function and use set -- "$backuppath"/*.sql
to put results into the array-like object "$@"
, after which you could refer to the first match as "$1"
, or the full set of matches as "$@"
.Upvotes: 9