红联Linux门户
Linux帮助

(已解决)脚本如何判断参数 文件/目录 的位置

发布时间:2011-05-07 13:55:09来源:红联作者:wewe-b
[i=s] 本帖最后由 wewe-b 于 2011-5-23 18:16 编辑 [/i]

例如:判断一个文件是否在根目录下,参数支持相对路径(如: file 或 ../file ) 。该如何写?
文章评论

共有 9 条评论

  1. wewe-b 于 2011-05-23 18:15:34发表:

    9# yanyongkg


    嗯嗯。讲得非常详细。考虑得很周到。
    "${1%/?*}" 这个用得很精髓。又学到不少。
    以后有问题再在论坛或IRC上请教您。谢谢 ^_^

  2. yanyongkg 于 2011-05-23 11:45:38发表:

    [code]
    #!/bin/bash
    #脚本$1为文件或目录都考虑进去了,但是为文件或为目录没有去做判断然后单独处理,笼统得处理$1参数的
    #也可用目录末尾加/符号,前面几楼提到的问题都已修复
    #此脚本只能使用一个参数(比如test.sh /boot/grub/ 当然test.sh所在目录要加入PATH中去)
    #若想使用多个参数,可以加个for ((i=1;i<=10;i=i+1))循环,$i变量来表达参数变量$1,$2等。


    #判断是否有$1参数变量,如果没有$1,则返回没有操作对象等信息
    if [ "$1" == "" ];then
    echo "it's need an option"
    #否则,也就是有$1参数变量,执行以下代码段
    else
    #判断$1是否以/开头
    if [ "${1::1}" == "/" ];then
    #判断$1这个文件或目录是否存在
    if [ -e "$1" ];then
    #这里修复了删目录末尾不能加/符号的漏洞
    #[[ -n "${1#/*/}" && -n "${1%/*}" ]]可以替换为[ -n "${1%/?*}" ]
    #此用法避免了/boot/也符合[ -n "${1%/*}"]的尴尬,因为/是最小匹配/*这个的,而/不能匹配/?*这个,问号代替换一定有一个字符
    #上面的一条,待求正,目前测试没发现/?*用法有误。。。
    if [[ -n "${1#/*/}" && -n "${1%/*}" ]];then
    rm -ir "$1"
    else
    echo "$1 in the rootdir(/),NO REMOVING"
    fi
    else
    echo "$1 doesn't exist"
    fi
    #如果$1不是以/开头,先要想办法找出$1的绝对路径
    else
    #此处修复了在当前在/boot目录下,可以test.sh ../lib删除的尴尬。
    #以当前工作路径和$1的相当路径得出$1的绝对路径再做判断
    dirX=$(cd "`pwd`/$1";pwd)
    if [ -e "$dirX" ];then
    if [ -n "${dirX%/?*}" ];then
    rm -ir "$dirX"
    else
    echo "$dirX in the rootdir(/),NO REMOVING"
    fi
    else
    echo "$dirX doesn't exist"
    fi
    fi
    fi
    [/code]我已经写得很是罗嗦了,希望对你有帮助
    发贴交流太慢了,有空可以上红联IRC频道,这样交流更方便,我经常挂线

  3. yanyongkg 于 2011-05-23 00:35:16发表:

    7# wewe-b

    你用了变量的替换删除以及去头去尾用法,比我去用grep去判断要聪明,我当时第一个想到了grep就用它了,:)
    顺便说句,${a:0:3}可以简写成${a::3}
    1。我前面的那个脚本,最外层一个if else是判断$1是否以/开头
    2。如果$1是以/开头,再判断文件是否层在,如果存在再if来判断有几层目录,以/的个数来判断,如果只有一层返回不允许删除,else否则就rm。如果文件不存在就返回不存在信息。
    3。如果$1不是以/开头,先if判断当前目录位置,如果当前在/,再判断/$1文件是否存在,存在再判断$1有几层也是以/符号的个数来判断,如只有一层说明此文件在/下返回不允许删除,如有一层以上则rm,如文件不存在返回不存在。
    4。else当前目录不在/下,再判断$currentdir/$1也就是此文件的路么是否存在,如果存在就rm,如不存在返回不存在信息


    说明:
    一。我上面的第四点还有个小问题,比如我当前在/boot下,也符合else的判断当前不在/下,test.sh ../lib 是可以删除/lib目录的,这个我昨天晚上睡觉时突然想到还有这个漏洞。这个可以修改
    二。前面我也有说明,因为我脚本中有用到去判断/符号的个数,所以删目录时目录尾不要加/符号。这个也可以修改的
    三。以上信息供参考,你可以结合自己的想法,改成自己想要的脚本,把上面的一。二。的问题都可以一并解决的

  4. wewe-b 于 2011-05-22 19:02:25发表:

    [i=s] 本帖最后由 wewe-b 于 2011-5-22 19:12 编辑 [/i]

    6# yanyongkg


    非常感谢热心指导。凌晨一点半还在回我的贴。从您的脚本中受到了启发。第一次看到 <<< 的运用,不知哪本教程有详述。呵呵。
    经过思考写了个脚本。请看看是否还有错漏。[code]#!/bin/bash

    #获取参数的相对路径 , 赋值于 Current
    if [ "${1:0:3}" == "../" ]; then
    Current=`cd ..;pwd`
    else
    Current=`pwd`
    fi

    # 比较绝对路径,如果在根目录下。则 ${1%/*} 为 空。输出错误提示。
    # 如果是相对路径则比较当前目录是否为 / 。
    if [ "${1%/*}" == "" ] || [ "$Current" == "/" ] ;then
    echo -e "\n \E[33;1mWarning !! : $1 in the rootdir(/),NO REMOVING !\n\E[0;0m"
    exit 1
    fi
    echo Now is removing ......
    rm -rf "$1"[/code]

  5. yanyongkg 于 2011-05-22 01:22:43发表:

    [i=s] 本帖最后由 yanyongkg 于 2011-5-22 01:30 编辑 [/i]

    [code]
    #!/bin/bash
    currentdir=$(pwd)
    a=$(grep '^/.*' <<< "$1")
    b=$(grep '^/.*/.*' <<< "$a")
    c="$currentdir/$1"
    d=$(grep '/' <<< "$1")
    if [ -n "$a" ];then
    if [ -e "$a" ];then
    if [ -z "$b" ];then
    echo "$1 in the rootdir(/),NO REMOVING"
    else
    rm -ir "$1"
    fi
    else
    echo "$1 doesn't exist"
    fi
    else
    if [ "$currentdir" == "/" ];then
    if [ -e "/$1" ];then
    if [ -z "$d" ];then
    echo "$1 in the rootdir(/),NO REMOVING"
    else
    rm -ir "$c"
    fi
    else
    echo "$c doesn't exist"
    fi
    else
    if [ -e "$c" ];then
    rm -ir "$c"
    else
    echo "$c doesn't exist"
    fi
    fi
    fi
    [/code]你不说明要做什么,我不知道你要实现什么,我就以你的rm为例,文件或目录在/下就不删除,否则删除。
    有一点要注意的是,我写的这个脚本删除目录时目录末尾不要加/,比如说test.sh /boot不能写成test.sh /boot/。因为我脚本里面没做判断$1是文件还是目录,要做这个判断太麻烦了。而且我脚本中用的grep有去判断$1中/符号的个数且没有考虑$1末尾的/符号,所以不能用test.sh /boot/来删除目录

    脚本判断了文件后的rm处理和echo处理换成你想要的相应处理就可以达成你要实现的功能。当然还得做一些改动,比如上面提到的删除目录时目录后不能加/
    权当供你参考,仅此。

  6. wewe-b 于 2011-05-21 17:36:34发表:

    4# yanyongkg


    echo Worng 跟 ls 是一个比如。其实获得路径后分别作不同的处理。

    例如脚本中有 rm 命令。 如果参数路径是根目录则显示错误信息并中断脚本,防止删除根目录。否则执行另一个处理。

  7. yanyongkg 于 2011-05-20 23:05:58发表:

    引用:
    2# yanyongkg



    谢谢回贴。是我问题表达的不够清楚。

    其实我是想这样的: 用一个脚本判断参数 $1
    $1 有可能是绝对路径,例如: /home/sam/file
    也可能是相对路径,例如: file 或 ../file 这个 ...
    wewe-b 发表于 2011-5-20 21:19


    你表达的意思很是费解。没看明白你要实现什么功能。按你的表述来说明,以下以文件file为例:
    1。#test.sh /home/sam/file 注释:若/home/sam/file文件存在,file不在/目录,ls $1来处理,屏幕返回file文件名
    2。#test.sh /file 注释:若/file存在,file在/目录,用echo WRONG处理,屏幕返回WRONG
    3。[/home]#test.sh ../file 注释:当前在/home下执行的test.sh,若/home/../file存在,即是/file存在,file在/目录,屏幕也返回WRONG
    你是这个意思?我实在看不出这样做有什么用处

  8. wewe-b 于 2011-05-20 21:19:23发表:

    [i=s] 本帖最后由 wewe-b 于 2011-5-20 21:25 编辑 [/i]

    2# yanyongkg



    谢谢回贴。是我问题表达的不够清楚。

    其实我是想这样的: 用一个脚本判断参数 $1
    $1 有可能是绝对路径,例如: /home/sam/file
    也可能是相对路径,例如: file 或 ../file 这个要根据当前路径来判断。
    可能是文件或目录。前路径

    脚本主要判断 $1 的位置,/ 目录与非 / 目录进行不同的处理。
    如果在 / 目录下则执行 echo Wrong 之类的处理。否则 ls $1 。
    请问该怎么写?

  9. yanyongkg 于 2011-05-13 10:20:41发表:

    [code]#!/bin/bash
    read -p "Please input filename or dirname:" name
    if [ -e /"$name"];then
    echo "this file or dir exist in the /"
    else
    echo "this file or dir does not exist in the /"
    fi[/code][code]#sh test.sh
    Please input filename or dirname:boot
    this file or dir exist in the /
    [/code][code]#sh test.sh
    Please input filename or dirname:asdg
    this file or dir does not exist in the /
    [/code]