0

I have a line like this. It breaks with an error, no such file or directory.

LB=$(ls "$f *.backup" | sort --reverse | head -n 1)

If I do this, it kinda works, just spits wrong filenames:

LB=$(ls $f *.backup | sort --reverse | head -n 1)

How do I solve this?

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
ArekBulski
  • 4,520
  • 4
  • 39
  • 61
  • 2
    What's the actual file name you're trying to match? – choroba Apr 14 '21 at 11:05
  • Do you have spaces in your filenames? Do you really mean `"$f"/*.backup`? It's unclear what you're trying to do here, so it's hard to tell which answer is correct (the existing ones make different assumptions about how to read the question, since the question is ambiguous). – Charles Duffy Apr 14 '21 at 11:10
  • Well yes, filenames might contain spaces. Not the files I tested it on, but in general yes. – ArekBulski Apr 14 '21 at 11:14
  • When glob characters are quoted, they lose their special meaning: `echo *` vs `echo "*"` – glenn jackman Apr 14 '21 at 12:04
  • DON'T use the `script` tag. It offers no information at all. All SO questions are about scripts one way or another. It's no better than adding `program` or `code`. – Panagiotis Kanavos Apr 22 '21 at 07:30

2 Answers2

1

Double quote the variable and the space, don't quote the wildcard.

"$f "*.backup
choroba
  • 231,213
  • 25
  • 204
  • 289
  • Has the OP made it clear that the space is an intentional part of their filename? (This might be right, but I don't think they've given us enough to know). – Charles Duffy Apr 14 '21 at 11:19
1

Filename expansion wildcards aren't evaluated in quotes. You'd have to escape the space or include it in quotes (And leave the wildcard out). And you don't want to parse ls. One way to safely get the last file based on alphabetical order, no matter the filenames and if they have newlines or other funny characters in them:

files=( "$f "*.backup )
lb="${files[-1]}"

That is, use an array to hold all the expanded files (Sorted by name) and then get the last element. You also shouldn't use upper case variable names unless you're exporting it to the environment of child processes.

Shawn
  • 47,241
  • 3
  • 26
  • 60
  • If there's the possibility of no files matching the pattern, you'll want to look into the nullglob bash option and checking the length of the array before using it. – Shawn Apr 14 '21 at 11:12
  • Even if you _are_ exporting a variable, it still should have a name with at least one lower case character unless it's intentionally overriding a reserved name defined by POSIX or your shell. See https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html: *The name space of environment variable names containing lowercase letters is reserved for applications. Applications can define any environment variables with names from this name space without modifying the behavior of the standard utilities.* – Charles Duffy Apr 14 '21 at 11:13
  • ...whereas with all caps environment variable names, whether there will be side effects on utility behavior is undefined – Charles Duffy Apr 14 '21 at 11:14
  • (Unless your shell is zsh, in which case its authors don't care about what POSIX says at all and just substitute their personal judgement, making even all-lowercase names able to change shell behavior) – Charles Duffy Apr 14 '21 at 11:16