2011-08-28 60 views
1

首先,我需要在Ruby和Bash腳本之間使用相同的信息。如何通過YAML在Ruby和Bash之間共享數據?

我從來沒有這樣做,要麼從來沒有使用YAML。我爲什麼想到YAML,Ruby是否從標準庫中得到了很好的支持。問題是我找不到關於Bash和YAML交互的任何信息。我想寫一些YAML文件(比如說foo.yml)並在兩個腳本中使用它的內容:bar.rb和baz.sh.

也許YAML的用法是錯的嗎?在程序之間共享數據的最正確方法是什麼?

+0

什麼樣的數據?在Bash中使用Yaml聽起來並不好玩,但如果你的結構相當簡單,也許這是可行的。 – tripleee

+0

Ruby程序是一個命令行工具。 Bash腳本是一個存儲在/etc/bash_completion.d/foo中的文件。我想使用YAML來存儲Ruby程序的命令行選項。爲什麼我需要這個?我認爲YAML將是在這兩種程序之間共享命令行選項的簡便方法(DRY原則或其他)。所以,基本上,Bash腳本是自動完成的腳本。我不想兩次寫入相同的選項(在兩個程序中),foo.yml應該可以幫到我。 – kyrylo

+2

爲什麼不根據你的YAML文件生成自動完成配置?這些選項不會一直在改變,所以爲什麼還要努力使自動完成配置成爲動態的呢? –

回答

1

YAML支持bash不支持的複雜數據結構。想到的第一個例子是關聯數組。

我會建議從Ruby生成適當的數據結構,並在bash中給出它們。

. <(/path/to/your/ruby/script --generate-completion-data) 

時--generate完成數據叫應該是一個有效的bash腳本的Ruby腳本的輸出,定義您將在完成腳本/程序

例如使用變量:

CMD_OPTS=(--help --print --version) 
CMD_F_OPTS=(--audio --video) 

而且你完成腳本可能看起來像:

. <(/path/to/your/ruby/script --generate-completion-data) 

__is_file_opt { 
    for element in ${CMD_F_OPTS[*]}; 
     if [[ $1 == $element ]]; then 
      return 0; 
     fi 
    done 
    return 1; 
} 
__ruby_script_complete { 
    local cur prev 
    COMPREPLY=() 

    #_get_cword is a function defined by /etc/bash_completion in Ubuntu, returns 
    # the current word to complete may not be available in your version 
    cur=`_get_cword` 

    prev=${COMP_WORDS[COMP_CWORD-1]} 

    if [[ "$cur" == -* ]]; then 
     COMPREPLY=($(compgen -W "${CMD_OPTS[*]} ${CMD_F_OPTS[*]}" -- "$cur"))    
     return 0; 
    fi 

    if __is_file_opt $prev; then 
     COMPREPLY=($(compgen -f -- $cur) \ 
        $(compgen -d -- $cur)) 
    fi 
    return 0 

} 

注意:上面的腳本沒有經過測試,只是一個例子

+0

嗯,謝謝,但我最終用Regexp解析了命令行Ruby實用程序的'help'命令。爲什麼?因爲每個人都這樣做,所以它看起來很自然。和YAML ......可能這是一個矯枉過正的問題。 – kyrylo