分页: 1 / 1

输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-11 23:46
dreamrider2011
scrips如下:
read -p "Please input dir name: " dir
if [ "$dir" == "" -o ! -d "$dir" ]; then
echo "The $dir is not exist in you system."
exit 1
fi
filelist=`ls $dir`
if filename in $filelist
do
perm=""
test -r "$dir/$filename" && perm="$perm readable"
test -w "$dir/$filename" && perm="$perm writable"
test -x "$dir/$filename" && perm="$perm execute"
echo "The $dir/$filename 's permission is $perm."
done
说明:一般目录都能正常显示,但是当我输入目录:~,显示错误,含有~的都会错。
我试了下加了句检测~存在,然后把它换成相关目录,还是错的。

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-12 10:19
wjchen
我改了一下,应该可以了

代码: 全选

#!/bin/bash

read -p "Please input dir name: " dir
eval "if [ -z "$dir"  -o ! -d "$dir" ];then echo "The $dir is not exist in your system.";exit 1;fi"
filelist=`eval ls $dir`
for filename in $filelist
do 
perm=""
eval test -r "$dir/$filename" && perm="$perm readable"
eval test -w "$dir/$filename" && perm="$perm writable"
eval test -x "$dir/$filename" && perm="$perm execute"
echo "The $dir/$filename 's permission is $perm."
done

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-13 0:00
dreamrider2011
你好,我试了下,可以。但能告诉我这是为什么吗?为什么加个eval就可以,我看了下man,没有发现要找的原因。谢谢。

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-13 9:16
wjchen
man bash 看一下eval的解释吧。

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-21 21:54
tusooa
應該寫成
dir="$1"
這樣在命令行裏就被解釋了。

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-21 22:23
dreamrider2011
你好,那个是运行脚本后,再输入文件名,不是将文件名作为参数。

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-21 22:24
dreamrider2011
wjchen 写了:man bash 看一下eval的解释吧。
抱歉,不介意的话能直接解释下吗?还是没找到。

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-21 23:35
Dohw0Doh
也来修改一下:

代码: 全选

#!/bin/bash

read -p "Please input dir name: " dir
# 重新解析一下目录名
eval dir="$dir"
if [ ! -d "$dir" ]; then
	echo "The $dir is not exist in your system."
	exit 1
fi

filelist=$(ls "$dir")
for filename in $(echo "$filelist"); do
	test -r "$dir/$filename" && perm="readable"
	test -w "$dir/$filename" && perm="$perm writable"
	test -x "$dir/$filename" && perm="$perm executable"
	echo "The permission of $dir/$filename is $perm"
done
exit 0
要学习eval命令, 需要理解shell的解析过程, 具体的可参考一下<Unix Shell编程(第三版)>, 非常推荐这本书.
另附我的学习笔记 -- shell解析过程

代码: 全选

shell解析执行命令的过程:
       1) 将命令解析为由固定的元字符分隔的单元。元字符包括:空格、制表符、新行、( ) < > | &。
               单元包括字、关键字、I/0 重定向符、分号等。
       2) 检查各单元前面的部分,以确定它是否为shell关键字,如function或if声明或反斜线。
               当找到关键字时,shell会运行这一组命令。
       3) 搜索别名列表。
       4) 展开所有~表达式。
       5) 替换变量。
       6) 替换命令。
       7) 替换算术表达式。
       8) 拆分那些由变量、命令和算术替换的结果得到的项,并再次分解成字。
       9) 展开通配符。
       10) 检查内置命令、函数和可执行的文件。
       11) 设置I/O重定向
简单地说:
       1.根据 空白、|、>、<、&、()、{} 这些元字符确定整个命令的结构和各个语法单元
               此时命令结构(如是否是IO重定向,是否置于后台等等)已经确定
       2.对各语法单元进行变量替换,命令替换,通配符展开等等,然后将这些替换后的字进行再分解
       3.构造环境,执行

实验:
       1.元字符 与 变量替换:元字符的抓取在变量替换之前,故变量替换出的元字符不成为元字符
               ################~的替换在变量替换之前
               $home='~/shao/'
               $cd $home
               ksh: ~/shao/: 找不到。

               ################|的特殊含义识别在变量替换之前
               $ pipe='|'
               $ ls $pipe wc -l
               ls:0653-341 文件 | 不存在。
               ls:0653-341 文件 wc 不存在。
               ls:0653-341 文件 -l 不存在。

       2.替换后的再分解
               ################命令替换的再分解
               $ cat mom
               m1
               m2
               m3
               abdfg
               m5
               m6
               m7
               $ echo `cat mom`
               m1 m2 m3 abdfg m5 m6 m7
               
               ################变量替换的再分解
               $ sisi='hao a'
               $ echo "$sisi"
               hao a
               $ echo $sisi
               hao a

               ################再分解不会再识别如|、>此类的元字符
               $ cmd0='ls -l | wc -l'
               $ $cmd0
               ls:0653-341 文件 | 不存在。
               ls:0653-341 文件 wc 不存在。
               ls:0653-341 文件 -l 不存在。
               
               $ cmd1='ls -al'
               $ $cmd1
               总计 72
               drwxr-xr-x 2 tinysisi cuteman 256 11月27 18时13 .
               drwxr-xr-x 3 tinysisi cuteman 4096 11月26 12时32 ..
               -rw-r--r-- 1 tinysisi cuteman 62 11月27 15时03 0
               -rw-r--r-- 1 tinysisi cuteman 497 11月27 18时13 00
               -rw-r--r-- 1 tinysisi cuteman 477 11月27 18时13 01
               -rw-r--r-- 1 tinysisi cuteman 23 11月27 16时15 Meimei.log
               -rw-r--r-- 1 tinysisi cuteman 24 11月27 10时09 mom
               -rw-r--r-- 1 tinysisi cuteman 23 11月27 16时15 sisi
               -rw-r--r-- 1 tinysisi cuteman 6 11月27 10时17 son0
               -rw-r--r-- 1 tinysisi cuteman 18 11月27 10时17 son1
               
               $ cmd2='ls -al > 0'
               $ $cmd2
               ls:0653-341 文件 > 不存在。
               -rw-r--r-- 1 tinysisi cuteman 62 11月27 15时03 0
               
原则:
       不用变量存储特殊元字符,如|、;、>、<等
       若存储了元字符,则考虑使用eval命令

eval的本质:让shell对命令行扫描两遍
        ############输出最后一个参数
        $ echo \$$#
        $3
        $ set ab cd ef
        $ echo \$$#
        $3
        $ eval echo \$$#
        ef
        ############再一例
        $ fn='ls -l|wc -l'
        $ $fn
        ls:不是可识别的标志:|
        ls:不是可识别的标志:w
        用法:ls [-1ACFHLNRabcdefgimnopqrstuxEUX] [File...]
        $ eval $fn
        9

shell 中的搜索顺序:
-------------
1,shell首先检查命令是不是保留字(比如for 和do );

2,如果不是保留字,并且不在引号中,shell接着检查别名表(alias);如果找到匹配则进行替换;如果别名定义以空格结尾,则对下一个词作别名替换。接着把替换的结果再跟保留字表比较,如果不是保留字则shell转入第3步;

3,然后,shell在函数表中查找该命令,如果找到则执行;

4,接着shell再检查该命令是不是内部命令(比如cd和pwd);

5,最后,shell在PATH中搜索以确定命令的位置;

6,如果还是找不到命令,则产生“command not found“错误信息。

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-22 1:16
dreamrider2011
非常感谢。书我会看的,谢谢。目前在看《鸟哥的Linux私房菜基础学习篇》。看完后,接着服务器篇。最后会看下你的那本shell 编程。你觉得怎样,我是说,你对这几本书有没有个人见解?
PS:关于eval使用,真是从man里没领会。

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-22 1:23
枫叶饭团
这几本书,我都没看过。。。。
手上只有一个《linux程序设计》的小白路过

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-09-22 9:15
Dohw0Doh
学shell很久了, 还好留有笔记.
*nix脚本编程方面的书单(这几本大致都翻过, 有本还读了两三遍, 感觉收获很多):
* Linux与Unix shell编程指南
* Unix shell编程(第三版)
* O'Reilly SED and AWK (second edtion)
然后就多写脚本, 还有系统里都有成百上千的脚本, 读读的话有很有提高的(比如, 如何实现系统服务的管理, 可以参考/etc/init.d/里的各种脚本)
服务器方面的主要是直接在Debian中搭环境慢慢玩, 比如nginx, apache, samba, dns, mail, vpn, ssh... 这些主要是配置选项的问题, 像apache 这样的可配置能力要求很强的, 得多练练

Re: 输入目录名找目录内文件名权限:shellscripts小问题

发表于 : 2012-10-01 13:51
tusooa
8樓的肯定不是GNU ls