电脑技术学习

对话 UNIX: Squirrel--可移植的 shell 和脚本语言

dn001

  在这里非常适合使用表这种数据结构。reveal() 中的表有两个 slot:一个用于文件,另一个用于目录。filetype( name ) 函数的返回值 — 常量 FILE 或常量 DIR — 将文件系统中的每一项整理到相应的 slot 中。

  此外,每个 slot 是一个数组,由 tally[FILE] <- [] 和 tally[DIR] <- []; 这两条语句创建。([] 是一个空数组)。由于 tally 是函数内的本地变量,它将在每次调用时重新创建并清空范围,并且在每个调用被返回时自动销毁。

  数组函数 append( arg ) 将 arg 添加到数组的末尾,从而在此过程中形成了一个列表。在执行完 foreach( index, name in names ) 循环后,所有项都被添加到这两个 slot 中其中一个的列表中。函数其余部分的代码将输出文件,接着输出目录,然后是递归。

  当然,如果没有命令行参数的话,shell 脚本的价值就没有那么大了。特殊 Squirrel Shell 变量 __argc 和 __argv 分别以字符串数组形式包含命令行参数的计数和参数列表。根据约定,__argv[0] 始终都作为 shell 脚本的名称;因此,如果 __argc 的值至少为 2,那么将提供额外的参数。为了简单起见,这个脚本只处理第一个额外参数 argv[1]。

  作为参考,清单 4 展示了一个 Ruby 脚本(作者为 Mr. Makshin),此脚本的功能与清单 3 相同。即使该脚本已像 Ruby 那样简洁,但它在简洁性方面仍然逊色于 Squirrel Shell 代码。

  清单 4. 使用 Ruby 重新实现清单 3

 
!/usr/bin/ruby 
 
# List Directory contents. 
 
path = ARGV[0] == nil ? "." : ARGV[0].dup 
 
# Remove trailing slashes 
while path =~ //$/ 
 path.chop! 
end 
 
entrIEs = Dir.open(path) 
for entry in entries 
 unless entry == "." || entry == ".." 
  filePath  = "#{path}/#{entry}" 
  fileStat = File.stat(filePath) 
  if fileStat.directory? 
   puts "dir : #{filePath}" 
  elsif fileStat.file? 
   puts "file: #{filePath}" 
  end 
 end 
end 
 
entries.close() 

标签: