BASH:为变量指定特殊符号

时间:2017-04-10 12:57:19

标签: bash

作为系统管理员,我必须使用不同的键盘布局在不同的服务器上工作。所以,每当我找到像'&'这样的钥匙的巨大问题时, '|'。

有什么办法可以将这些符号分配给变量并在需要符号时调用变量吗?

例如:假设

knex('title as t')
  .select('t.id', 't.title', 's.userId')
  .leftJoin('subscribe as s', (builder) => {
    builder.on('t.id', 's.titleId').on('s.userId', knex.raw('?', [1]));
  })

应该给我运行java进程。我尝试了一切,但失败了。

请帮忙。

3 个答案:

答案 0 :(得分:3)

以下功能可以完成这项工作:

# read a number of arguments on the left-hand side; those actual arguments; then the RHS
pipe() {
  local nargs
  local -a firstCmd

  nargs=$1; shift
  firstCmd=( )
  for ((i=0; i<nargs; i++)); do
    firstCmd+=( "$1" ); shift
  done
  "${firstCmd[@]}" | "$@"
}

# basic use case
pipe 3 ps -ef somethinghere grep java

# or, for a pipeline with more than two components:
pipe 3 ps -ef somethinghere pipe 2 grep java tee log.txt

与使用eval解决方案相比,更好的是,它甚至能够处理更复杂的值:

pipe 3 ps -ef 'something with spaces here' grep java

还可以编写一个使用sigil值的函数版本:

pipe() {
  local sigil
  local -a firstCmd

  sigil=$1; shift
  firstCmd=( )
  while (( $# )); do
    if [[ $1 = "$sigil" ]]; then
      shift
      "${firstCmd[@]}" | pipe "$sigil" "$@"
      return
    else
      firstCmd+=( "$1" )
      shift
    fi
  done
  "${firstCmd[@]}"
}

在这种情况下,你甚至可以这样做:

sigil=$(uuidgen) # generate a random, per-session value
pipe "$sigil" ps -ef 'something with spaces here' "$sigil" grep java "$sigil" tee log.txt

答案 1 :(得分:2)

如果你真的想这样做,可以采取以下方式:

pipe="|"
eval $(echo ps -ef $pipe grep java)

与猫:

eval $(echo ps -ef $(cat pipe.txt) grep java)

请注意,不建议使用eval,只要您需要包含引号,转义序列,文件名和/或带空格的参数等的复杂命令,此命令就会出现问题。

在我看来,您最好熟悉如何在不同的Linux系统上更改键盘布局(例如,请参阅loadkeys)。

答案 2 :(得分:1)

建立在与CharlesDuffy提出的第一个解决方案相同的逻辑上,这应该是等价的:

pipe()
{
    "${@:2:$1}" | "${@:$(($1+2))}"
}

该解决方案使用扩展,而不是使用迭代来构建具有第一个命令和移位参数的数组,直到其余的仅包含第二个命令。

  • "${@:2:$1}"展开$1个参数,从第2位开始
  • "${@:$(($1+2))}"展开从位置$1 + 2开始的所有参数。

在这两种情况下,双引号确保参数扩展为每个参数一个单词(不执行单词拆分)。

如果你觉得这太神秘了,可以随意避免它,因为可读性(对于那些有一天必须维护代码的打算的编码人员)可能胜过任何优势。