2014-06-07 186 views
0

使用SH shell脚本在FreeBSD 8.3中遇到问题。变量替换

在FreeBSD下

date -j -f "%Y/%m/%d" "$ii" '+%s' 

该脚本需要在两个FreeBSD和Ubuntu的运行,但日期函数并不在Ubuntu工作下date命令的作品。

这工作在Ubuntu

date --date="$ii" +"%s" 

所以我希望有一个变量取决于操作系统这两者之间进行切换。

# Options (freebsd/linux) 
recdate=freebsd 

ii=2014/06/06 

if [ "$recdate" == "freebsd" ]; then 
    recdate="\`date \-j \-f \"\%Y/\%m/\%d\" \"\$ii\" \'\+\%s\'\`" 
else 
    recdate="\`date \-\-date\=\"\$ii\" \+\"\%s\"\`" 
fi 

我试过多次转义和引用没有成功。

错误如下(使用set -x):

+ [ '' == freebsd ] 
+ date --date= +%s 
date: illegal option -- - 
usage: date [-jnu] [-d dst] [-r seconds] [-t west] [-v[+|-]val[ymwdHMS]] ... 
     [-f fmt date | [[[[[cc]yy]mm]dd]HH]MM[.ss]] [+format] 
+ recdate='' 
+1

'+ [''== freebsd]'给你提示了吗? – devnull

+0

这是使用非标准扩展的麻烦;你会得到非标准化的行为。 –

+0

http://mywiki.wooledge.org/BashFAQ/053 – tripleee

回答

5

由于@devnull在评论中指出,你的OS测试失败,因为你的$recdate变量实际上是空,就是明证应用set -x后的+ [ '' == freebsd ]输出行。

需要注意的另一件事是,您正在合并[ ... ](POSIX语法)和==bash语法)。
使用=[ ... ][ "$recdate" = "freebsd" ]

至于检测FreeBSD,我建议你做:

if [ "$(uname)" = "FreeBSD" ]; then .... 

或者,如果你想设置一个标志:

[ "$(uname)" = "FreeBSD" ] && isFreeBSD=1 || isFreeBSD= 

# ... 

if [ $isFreeBSD ]; then # .... 

最后,您构建的方式命令很尴尬。

我建议你创建一个封装了两个平台之间的差异壳功能:

# Shell function that encapsulates differences between FreeBSD and Linux. 
toEpochTime() { 
    if [ "$(uname)" = "FreeBSD" ]; then 
    date -j -f "%Y/%m/%d" "$1" '+%s' 
    else 
    date --date="$1" +"%s" 
    fi 
} 

# Invoke the function 
toEpochTime '2014/06/06' 

有感

的评论说,这是低效的执行@chepner指出每次调用函数时确定主机操作系统的条件。

他建议使用条件一次定义功能平台,特别是(注意,虽然其它语言可能在定义具有相同名称的函数两次,在if语句的不同分支放水,bash允许它):

# Define helper function `toEpochTime()` in a platform-dependent 
# manner, based on the output of `uname`: 
if [ "$(uname)" = 'FreeBSD' ]; then 
    toEpochTime() { date -j -f "%Y/%m/%d" "$1" '+%s'; } 
else 
    toEpochTime() { date --date="$1" +"%s"; } 
fi 

# Invoke the function. 
toEpochTime '2014/06/06' 
+1

我试过这两个操作系统和它的作品! – CA171

+0

我对整个脚本使用了类似的格式,这是它失败的唯一实例。我仍然想找到问题为什么不起作用。但我同意这是总体上最好的选择! – CA171

+0

@ CA171:你有没有试过在条件中使用_single_'=',建议如下:'[“$ recdate”=“freebsd”]'?什么外壳正在解释这个?在分配给recdate后'set -x'会显示什么? – mklement0