简体   繁体   中英

Add trailing slash to string variable

I have this script:

#!/bin/bash

[[ "$#" -gt 0 ]] && last_argument="${@:$#}" || last_argument=""
[[ -d $last_argument ]] && loc="${last_argument}/" || \
    [[ -f $last_argument ]] && loc="${last_argument}" || loc=""

list="ls -dlth $loc*/"

echo -e "$list"
eval "$list"

What I want it to do, is to check if the last argument is

  • a directory, execute ls -dlth $loc/*/ , (but it doesn't)

  • a file, produce an error (which it does),

  • empty, execute ls -dlth */ (which it does)

Now the problem is that in the line where I say loc="${last_argument}/" , no / is being added to the string variable, and the command being executed is ls -dlth $loc*/ which produces a different result. How can I fix this?

I tried escaping / with a \\ , but it didn't work:

loc="${last_argument}\/"

Running it with set -xv prints this:

[[ "$#" -gt 0 ]] && last_argument="${@:$#}" || last_argument=""
+ [[ 2 -gt 0 ]]
+ last_argument=/home/amir/Pictures
[[ -d $last_argument ]] && loc="${last_argument}/" || \
    [[ -f $last_argument ]] && loc="${last_argument}" || loc=""
+ [[ -d /home/amir/Pictures ]]
+ loc=/home/amir/Pictures/
+ loc=/home/amir/Pictures

The

[[ -d $last_argument ]] && loc="${last_argument}/" ||
[[ -f $last_argument ]] && loc="${last_argument}" || loc=""

is parsed as:

(
   (
       ( 
          [[ -d $last_argument ]] &&
          loc="${last_argument}/" 
       ) ||
       [[ -f $last_argument ]] 
    ) && 
    loc="${last_argument}"
) ||
loc=""

In your sample execution the [[ -d $last_argument ]] exits with a zero exit status (success), so loc="${last_argument}/" is executed. Then [[ -d $last_argument ]] && loc="${last_argument}/" returns with a zero exit status (success), so the [[ -f $last_argument ]] is not executed, but the whole [[ -d $last_argument ]] && loc="${last_argument}/" || [[ -f $last_argument ]] [[ -d $last_argument ]] && loc="${last_argument}/" || [[ -f $last_argument ]] also exits with a zero exit status (success) (because the left side of || exited with zero exit status (success)). That means that loc="${last_argument}" is executed, so you finally see + loc=/home/amir/Pictures in your script execution.

Note that \\ after || before a newline is not needed (you can even add a comment there).

I think you could group your statements:

{ [[ -d $last_argument ]] && loc="${last_argument}/" ;} ||
{ [[ -f $last_argument ]] && loc="${last_argument}" ;} ||
loc=""

Or just use if-elif-else-fi to have control over what happens.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM