通用“标题”和“页脚”,将被包含在一个脚本中以实现多行语句

问题描述:

为了减少追赶点,以下内容(源自Charles Duffy对相关问题的回复 - 请参阅his answer)将对于我的要求是可接受的格式:通用“标题”和“页脚”,将被包含在一个脚本中以实现多行语句

eval "$(
    { sed -E -e 's/^[ ]+//;' -e ':a;N;$!ba;s/\n//g' | tr -d '\n'; } <<'____COMMAND' 
sshfs 
[email protected]:/sftp_folder 
    /var/sshfs.sandbox/server.com 
    -o 
    user=foo_user 
    ,reconnect 
    ,ServerAliveInterval=15 
    ,ServerAliveCountMax=3 
____COMMAND 
)" 

注意,有每当它是由我试图分裂成multple行命令需要一个尾随空格:

sshfs 
[email protected]:/sftp_folder 
    /var/sshfs.sandbox/server.com 
    -o 

也没有尾随空格对于必须conca的选项

user=foo_user 
,reconnect 
,ServerAliveInterval=15 
,ServerAliveCountMax=3 

一旦级联,命令变为:中间没有空格tenated

sshfs [email protected]:/sftp_folder /var/sshfs.sandbox/server.com -o user=foo_user,reconnect,ServerAliveInterval=15,ServerAliveCountMax=3 

不过,我告诉尾随空格是一个坏主意,各地(再次,请参阅Charles Duffyreply为动机)

因此,我想知道。有没有办法实现所有这三个:

  1. 保持声明全部“在一起”。
  2. 没有尾随空白。
  3. 使“标题”和“页脚”固定并在其他脚本中可复制,无需修改。

我想用斜杠以及修改所述解析表达式:

{ sed -E -e 's/^[ ]+//;' -e ':a;N;$!ba;s/\n//g' | tr -d '\n'; } 

使得我可以实现上述的所有三个提及。

您是否考虑过使用带反斜杠的多行命令?这使尾随空间清晰可见。

从击手册:

3.1.2.1转义字符

非引用的反斜杠“\”是击转义字符。它保留了 下一个字符的字面值, 例外。如果出现\换行符对,并且反斜杠本身未被引用,\换行符将被视为续行 (也就是说,它将从输入流中移除,并且实际上 将被忽略)。

sshfs \ 
[email protected]:/sftp_folder \ 
/var/sshfs.sandbox/server.com \ 
-o \ 
user=foo_user\ 
,reconnect\ 
,ServerAliveInterval=15\ 
,ServerAliveCountMax=3,\ 

反斜杠/换行符诀窍是命令的正常解析的一部分,并且具有比忽略换行符没有其他的效果,所以你可以使用引号,你通常会做的方式。

从表达命令本身的角度来看,也许不那么干净,但不需要这里的文档或对sed的附加调用。

这就是说,CharlesDuffy在回答您的原始问题时建议使用基于数组的解决方案,并且根据我的经验,将命令和参数放置在数组中是根据我的经验,针对许多令人头疼的简单而有效的解决方案。有没有理由不想使用这种方法?

+0

您的解决方案将插入空格,即没有应该存在的位置(即“user = foo_user,reconnect,ServerAliveInterval = 15,ServerAliveCountMax = 3”)。 – user1712447

+0

“有没有你不想使用这种方法的原因?” :我只想在一个地方输入命令,我喜欢这种方式。 – user1712447

+0

你是对的,我忘了删除领先的空间。这是固定的。至于只在一个地方输入命令,为什么这种方法不允许你这样做?它可以放在一个脚本中的一个地方。 – Fred

希望这会做你想做的。

首先,定义一个函数,用于解析标准输入接收到的命令。

#!/bin/bash 

execute_command() 
{ 
    local -a command=() 
    local arg= 
    while IFS= read -r line 
    do 
    [[ $line =~ [[:blank:]]*(.*[^[:blank:]\\])(\\?)[[:blank:]]*$ ]] 
    if 
     [[ ${BASH_REMATCH[2]} ]] 
    then 
     arg+=${BASH_REMATCH[1]} 
    else 
     command+=("$arg${BASH_REMATCH[1]}") 
     arg= 
    fi 
    done 
    "${command[@]}" 
} 

然后,在您想要以下行被认为是相同参数的一部分每一行的末尾留下了尾随斜线调用这个函数。上面的代码不会执行任何解析,因此您不能在同一行放置两个参数(在您的示例中,您没有这样做,因此我认为这对您而言是一个可接受的限制)。

execute_command <<'____COMMAND' 
sshfs 
[email protected]:/sftp_folder 
    /var/sshfs.sandbox/server.com 
    -o 
    user=foo_user\ 
    ,reconnect\ 
    ,ServerAliveInterval=15\ 
    ,ServerAliveCountMax=3 
____COMMAND 

这为您提供了一个非常简单的,可重复使用的“头”,不需要(但容许)尾部的空格,让领先的所有线路上的空间,同时引入尽可能少的重/怪异的语法可能。

+0

有趣的拿,但我不能只复制粘贴页眉和页脚。我还必须复制粘贴功能(或将其包含在全局执行的脚本等中(这意味着我无法轻松分发包含页眉/页脚的脚本) – user1712447

+0

如果您要将脚本分发到执行外你可以控制的环境(即可以获得“库”脚本来源)的环境,为什么你想要使用这种非标准的表达命令的方式?在某个点上,将命令放在一个非常长的行上或者在连续的行,但没有缩进可能,即使不漂亮,结果是最好的折衷... – Fred

+0

为什么不把选项放在变量中,然后在一个(更短的)行上展开以执行命令? – Fred