如何转义文件路径中的路径分隔符?

时间:2013-12-29 03:46:22

标签: bash file path variable-assignment

我正在编写我的第一个bash脚本,并且无法为变量分配文件路径:

$target="/etc/httpd/conf/httpd.conf" 

似乎bash希望用“=”赋值运算符解释这个,导致脚本向“无此文件或目录”效果抛出错误。

有一种简单的方法吗?我发现我可以像这样分配一个常量的完整路径:

readonly TARGET=/etc/httpd/conf/httpd.conf

但这似乎相当麻烦。我如何执行字符串操作来修改/操作?

我还发现我可以将完整路径放在这样的数组中:

declare -a cfile=('/root/.bashrc' '/etc/fstab')

一切顺利,但如何为变量分配文件路径?

== == == ==

完成!我的第一个bash脚本 - 一个基本的配置文件管理器

#!/bin/bash

# cfmgr.sh - configuration file manager bash script
# options: -get, -put
# '-get' creates SOURCEDIR/USERDIR and copies config files to USERDIR
# '-put' copies files in SOURCEDIR/USERDIR to system-defined locations on server
# purpose: helps with moving LAMP VMs to different hosts, bulk edits of
# of config files in editors like Notepad++, and backing up config files.

readonly SOURCEDIR=/usr/bin/_serverconfig
while [[ $# > 0 ]]
do
    arg="$1"
    shift
    case $arg in
        -put)
            put=true
            ;;
        -get)
            get=true
            ;;
        *)
            badarg=true
            ;;
    esac
done
clear
if [ $badarg ]; then
    echo "Invalid argument. Use either 'scf.sh -put' or 'scf.sh -get' to put"\
        "or get config files."
    exit
elif [ $get ]; then
    echo "Enter directory name to store files cfmgr will GET from this server:"
elif [ $put ]; then
    echo "Enter directory name containing files cfmgr will PUT to this server:"
else
    echo "Use either 'scf.sh -put' or 'scf.sh -get' to put or get config files."
    exit
fi
read -e -i $SOURCEDIR"/" USERDIR
pattern=" |'"
if [[ $USERDIR =~ $pattern ]]; then
    echo "Spaces not allowed.  Please try again."
    exit
fi
declare -a cfile=('/root/.bashrc' '/etc/fstab' '/etc/hosts' '/etc/networks'\
    '/etc/php.ini' '/etc/nsswitch.conf' '/etc/ntp.conf' '/etc/resolv.conf'\
    '/etc/sysctl.conf' '/etc/httpd/conf/httpd.conf' '/etc/selinux/config'\
    '/etc/samba/smb.conf' '/etc/samba/smbusers' '/etc/security/limits.conf'\
    '/etc/sysconfig/network' '/etc/sysconfig/network-scripts/ifcfg-eth0'\
    '/etc/sysconfig/network-scripts/ifcfg-eth1')
if [ $get ]; then
    if [[ -d "$USERDIR" ]]; then
        echo $USERDIR "directory already exists. Please try again."
        exit
    else
        mkdir -m 755 $USERDIR
    fi
    for file in ${cfile[@]}
    do
        if [ -e $file ]; then
            rsync -q $file $USERDIR
            if [ $? -eq 0 ]; then
                sleep 0.1
                printf "# "$file"\n"
            fi
        else
            printf "not found: "$file"\n"
        fi
    done
elif [ $put ]; then
    if [[ ! -d "$USERDIR" ]]; then
        echo $USERDIR "directory does not exist. Please try again."
        exit
    fi
    id=0    
    cd $USERDIR
    for item in *
    do
        if [[ -f $item ]]; then
            cdir[$id]=$item
            id=$(($id+1))
        fi
    done    
    for file in ${cdir[@]}
    do
        case $file in
        .bashrc)
            idx=0
            ;;
        fstab)
            idx=1
            ;;
        hosts)
            idx=2
            ;;
        networks)
            idx=3
            ;;
        php.ini)
            idx=4
            ;;
        nsswitch.conf)
            idx=5
            ;;          
        ntp.conf)
            idx=6
            ;;
        resolv.conf)
            idx=7
            ;;
        sysctl.conf)
            idx=8
            ;;
        httpd.conf)
            idx=9
            ;;
        config)
            idx=10
            ;;
        smb.conf)
            idx=11
            ;;
        smbusers)
            idx=12
            ;;
        limits.conf)
            idx=13
            ;;
        network)
            idx=14
            ;;      
        ifcfg-eth0)
            idx=15
            ;;
        ifcfg-eth1)
            idx=16
            ;;
        *)
            printf "not found: "$file"\n"
            continue
        esac
        target=${cfile[$idx]}
        if [[ -e $target ]]; then
            dtm=$(date +%Y-%m-%d)
            mv $target $target"."$dtm
        fi
        source=$USERDIR"/"$file
        dos2unix -q $source
        rsync -q $source $target
        if [ $? -eq 0 ]; then
            sleep 0.1
            printf "# "$target"\n"
        fi
    done
    read -p "reboot now? (y|n)" selection
    case $selection in
    [Yy]*)
        `reboot`
        ;;
    *)
        exit
        ;;
    esac
fi  
exit 0

1 个答案:

答案 0 :(得分:2)

而不是

$target="/etc/httpd/conf/httpd.conf" 

使用:

target="/etc/httpd/conf/httpd.conf" 

当bash看到前者时,它首先替换为“$ target”。如果target为空,那么在变量替换和引用删除步骤之后bash尝试执行的行是:

=/etc/httpd/conf/httpd.conf

由于没有名为“= / etc / httpd / conf / httpd.conf”的文件,bash返回“没有这样的文件或目录”错误。