How to manually expand a special variable (ex: ~ tilde) in bash

前端 未结 15 2157
离开以前
离开以前 2020-11-22 09:34

I have a variable in my bash script whose value is something like this:

~/a/b/c

Note that it is unexpanded tilde. When I do ls -lt on this

相关标签:
15条回答
  • 2020-11-22 09:38

    A safe way to use eval is "$(printf "~/%q" "$dangerous_path")". Note that is bash specific.

    #!/bin/bash
    
    relativepath=a/b/c
    eval homedir="$(printf "~/%q" "$relativepath")"
    echo $homedir # prints home path
    

    See this question for details

    Also, note that under zsh this would be as as simple as echo ${~dangerous_path}

    0 讨论(0)
  • 2020-11-22 09:39

    Just use eval correctly: with validation.

    case $1${1%%/*} in
    ([!~]*|"$1"?*[!-+_.[:alnum:]]*|"") ! :;;
    (*/*)  set "${1%%/*}" "${1#*/}"       ;;
    (*)    set "$1" 
    esac&& eval "printf '%s\n' $1${2+/\"\$2\"}"
    
    0 讨论(0)
  • 2020-11-22 09:41

    How about this:

    path=`realpath "$1"`
    

    Or:

    path=`readlink -f "$1"`
    
    0 讨论(0)
  • 2020-11-22 09:41

    Here's my solution:

    #!/bin/bash
    
    
    expandTilde()
    {
        local tilde_re='^(~[A-Za-z0-9_.-]*)(.*)'
        local path="$*"
        local pathSuffix=
    
        if [[ $path =~ $tilde_re ]]
        then
            # only use eval on the ~username portion !
            path=$(eval echo ${BASH_REMATCH[1]})
            pathSuffix=${BASH_REMATCH[2]}
        fi
    
        echo "${path}${pathSuffix}"
    }
    
    
    
    result=$(expandTilde "$1")
    
    echo "Result = $result"
    
    0 讨论(0)
  • 2020-11-22 09:42

    Just to extend birryree's answer for paths with spaces: You cannot use the eval command as is because it seperates evaluation by spaces. One solution is to replace spaces temporarily for the eval command:

    mypath="~/a/b/c/Something With Spaces"
    expandedpath=${mypath// /_spc_}    # replace spaces 
    eval expandedpath=${expandedpath}  # put spaces back
    expandedpath=${expandedpath//_spc_/ }
    echo "$expandedpath"    # prints e.g. /Users/fred/a/b/c/Something With Spaces"
    ls -lt "$expandedpath"  # outputs dir content
    

    This example relies of course on the assumption that mypath never contains the char sequence "_spc_".

    0 讨论(0)
  • 2020-11-22 09:45

    If the variable var is input by the user, eval should not be used to expand the tilde using

    eval var=$var  # Do not use this!
    

    The reason is: the user could by accident (or by purpose) type for example var="$(rm -rf $HOME/)" with possible disastrous consequences.

    A better (and safer) way is to use Bash parameter expansion:

    var="${var/#\~/$HOME}"
    
    0 讨论(0)
提交回复
热议问题