代码之家  ›  专栏  ›  技术社区  ›  Dan Rosenstark

使环境变化在Ruby脚本中保持不变

  •  2
  • Dan Rosenstark  · 技术社区  · 14 年前

    这是我的剧本

    #!/usr/bin/env ruby
    if __FILE__ == $0
        `cd ..` 
        puts `ls` 
    end
    

    它运行良好,但当它退出时,我回到了我开始的地方。如何“导出”我对环境所做的更改?

    1 回复  |  直到 14 年前
        1
  •  6
  •   ib.    14 年前

    这是因为``运算符不适用于复杂的脚本编写。它对跑步很有用 单一的 命令(并读取其输出)。它后面没有用于存储环境更改的shell 之间 它的呼唤和 之后 您的Ruby脚本已终止。

    在Linux系统上,每个进程都有自己的“当前目录”路径(可以在/proc/_¹pid_º/cwd中找到)。更改进程中的目录不会影响父进程(从中运行程序的shell)。如果 cd 内置的是二进制的,它只能更改自己的当前目录,而不能更改父进程(这就是为什么 光盘 命令只能是内置的)。


    注释

    如果露比脚本 必须 从外壳执行 必须 影响shell的当前目录路径,可以进行“欺骗”。不是从Ruby本身运行命令,而是将该命令打印到stdout,然后 source 到运行ruby脚本的shell。命令将 由一个单独的shell进程执行,所以 光盘 S 在当前shell实例中生效。

    所以,而不是

    ruby run_commands.rb
    

    在shell脚本中编写如下内容:

    source <(ruby prepare_and_print_commands.rb)
    

    Shell

    但是在Ruby中有一个方便的命令行脚本编写工具 Shell 上课!它为常用命令(如 光盘 , pwd ,请 cat , echo 等),并允许定义自己的(它支持 命令 别名 )!它还透明地支持使用 | , > , < , >> ,请 << 红宝石运营商。

    一起工作 壳牌 大多数时候都是不言自明的。看看几个简单的例子。

    创建“shell”对象并更改目录

    sh = Shell.new
    sh.cd '~/tmp'
    # or
    sh = Shell.cd('~/tmp')
    

    在当前目录中工作

    puts "Working directory: #{sh.pwd}"
    (sh.echo 'test') | (sh.tee 'test') > STDOUT
    # Redirecting possible to "left" as well as to "right".
    (sh.cat < 'test') > 'triple_test'
    # '>>' and '<<' are also supported.
    sh.cat('test', 'test') >> 'triple_test'
    

    (注意,括号有时是必要的,因为“重定向”运算符的优先级。另外,默认情况下,命令输出不会打印到stdout,因此需要指定 > STDOUT > STDERR 如果需要的话。)

    测试文件属性

    puts sh.test('e', 'test')
    # or
    puts sh[:e, 'test']
    puts sh[:exists?, 'test']
    puts sh[:exists?, 'nonexistent']
    

    (类似于 test 在普通shell中的函数。)

    定义自定义命令和别名

    #                        name    command line to execute
    Shell.def_system_command 'list', 'ls -1'
    
    #                   name   cmd   command's arguments
    Shell.alias_command "lsC", "ls", "-CBF"
    Shell.alias_command("lsC", "ls") { |*opts| ["-CBF", *opts] }
    

    稍后可以使用定义的命令的名称来运行它,方法与它在预定义命令中的工作方式完全相同 回声 例如。

    使用目录堆栈

    sh.pushd '/tmp'
    sh.list > STDOUT
    (sh.echo sh.pwd) > STDOUT
    sh.popd
    sh.list > STDOUT
    (sh.echo sh.pwd) > STDOUT
    

    (这里是自定义 list 使用上面定义的命令。)

    顺便说一句,这是有用的 chdir 命令在一个目录中运行多个命令,然后返回到上一个工作目录。

    puts sh.pwd
    sh.chdir('/tmp') do
        puts sh.pwd
    end
    puts sh.pwd
    

    跳过一组命令的shell对象

    # Code above, rewritten to drop out 'sh.' in front of each command.
    sh.transact do
        pushd '/tmp'
        list > STDOUT
        (echo pwd) > STDOUT
        popd
        list > STDOUT
        (echo pwd) > STDOUT
    end
    

    其他功能

    此外 壳牌 有:

    • foreach 方法,通过文件中的行或目录中的文件列表(取决于给定路径是指向文件还是目录)进行迭代,
    • jobs kill 控制过程的命令,
    • 一堆操作文件的命令(比如 basename , chmod , chown , delete , dirname , rename , stat , symlink )
    • 一览表 File 方法的同义词( directory? , executable? , exists? , readable? 等)
    • 相当于 FileTest 类方法'。( syscopy ,请 copy ,请 move , compare , safe_unlink , makedirs ,请 install )