重新排列getopt输出,这样每次都会首先执行一个特定的参数(如果给定)

时间:2016-12-05 16:31:54

标签: bash shell getopt

有没有办法重新排列getopt。

查看使用gnu getopt的简单脚本。

public class GridTools
{
  @SuppressWarnings("unused")
  private static final Logger LOGGER = Logger.getLogger(GridTools.class.getName());

  /**
   * call immediately after setting container data source
   */
  public static void replaceKeyMapper(Grid grid) throws Exception
  {
    Field datasourceExtensionField = Grid.class.getDeclaredField("datasourceExtension");
    datasourceExtensionField.setAccessible(true);
    RpcDataProviderExtension rpcDataProviderExtension = (RpcDataProviderExtension) datasourceExtensionField.get(grid);

    Field activeItemHandlerField = RpcDataProviderExtension.class.getDeclaredField("activeItemHandler");
    activeItemHandlerField.setAccessible(true);
    Object activeItemHandler = activeItemHandlerField.get(rpcDataProviderExtension);

    Field keyMapperField = activeItemHandler.getClass().getDeclaredField("keyMapper");
    keyMapperField.setAccessible(true);
    keyMapperField.set(activeItemHandler, new NonCachingKeyMapper(grid));
  }

  private static class NonCachingKeyMapper extends KeyMapper
  {
    private Grid m_grid = null;

    public NonCachingKeyMapper(Grid grid)
    {
      m_grid = grid;
    }

    @Override
    public Object get(String key)
    {
      Object staleItemId = super.get(key);
      Optional freshItemId = m_grid.getContainerDataSource().getItemIds().stream().filter(i -> i.equals(staleItemId)).findAny();
      LOGGER.log(Level.INFO, "intercept: stale=" + staleItemId + ", fresh=" + freshItemId);
      return freshItemId.isPresent() ? freshItemId.get() : null;
    }
  }
}

输出:

#!/bin/bash
TEMP=`getopt -o abc -n 'test.sh' -- "$@"`
eval set -- "$TEMP"

while true ; do
    case "$1" in
        -a) echo "alpha"   ;shift ;;
        -b) echo "bravo"   ;shift ;
        -c) echo "charlie" ;shift ;;
        -d) echo "delta"    ;shift ;;
        --) shift ; break ;;
        *) echo "error!" ; exit 1 ;;
    esac
done

期望的输出:

$./alpha-project -c -a -b 
  charlie
  alpha
  bravo


$./alpha-project -b -c -a
  bravo
  charlie
  alpha

现在,无论-a放在哪个参数中,都必须先执行-a case。

3 个答案:

答案 0 :(得分:1)

一种解决方案是明确重新排列位置参数,如下所示

#!/bin/bash
# Say you want '-a' to be first every time
temp="$( getopt -o abc -n 'test.sh' -- "$@" )"
temp="$(sed -E ':l1;s/(-[^a]) (-a)/\2 \1/g;/-[^a] -a/bl1' <<< "$temp")" #re-arrangement part


while true ; do
    case "$1" in
        -a) echo "alpha"   ;shift ;;
        -b) echo "bravo"   ;shift ;; # A semicolon is missing in question
        -c) echo "charlie" ;shift ;;
        -d) echo "delta"    ;shift ;;
        --) shift ; break ;;
        *) echo "error!" ; exit 1 ;;
    esac
done

这将为您提供所需的结果。

示例运行

# ./40978894 -b -a -c -a
alpha
alpha
bravo
charlie
# ./40978894 -b -a -c
alpha
bravo
charlie
# ./40978894 -b -a -c -a -a
alpha
alpha
alpha
bravo
charlie

请注意,替换会执行一些繁重的管理输入,例如-b -a -c -a -a。对于涉及位置参数值的更复杂的情况,您需要更复杂的替换。

警告:对用户变量使用小写,即TEMP - &gt;温度

答案 1 :(得分:1)

  

第一次你可以解析-a和其他人。

#!/bin/bash
TEMP=`getopt -o abc -n 'test.sh' -- "$@"`

eval set -- "$TEMP"
while true ; do
    case "$1" in
        -a) echo "alpha"   ;break ;;
        -b|-c|-d) shift ;;
        *)  break ;;
    esac
done

eval set -- "$TEMP"
while true ; do
    case "$1" in
        -a) shift ;;
        -b) echo "bravo"   ;shift ;;
        -c) echo "charlie" ;shift ;;
        -d) echo "delta"    ;shift ;;
        --) shift ; break ;;
        *) echo "error!" ; exit 1 ;;
    esac
done

答案 2 :(得分:0)

您不应该在选项解析循环中执行任何操作。你应该只设置变量/配置,以便程序的其余部分完成它应该做的事情。当您这样做时,您的订购问题就会消失。

如果查看getopt source code,您会发现即使是工具本身也会在内部执行此操作。在选项循环中不执行任何操作,它只为程序的其余部分设置变量和数据结构。

您也可以这样做:

#!/bin/bash
temp=`getopt -o abc -n 'test.sh' -- "$@"`
eval set -- "$temp"

alpha=""
bravo=""
charlie=no
while true ; do
    case "$1" in
        -a) alpha=1     ;shift ;;
        -b) bravo=1     ;shift ;;
        -c) charlie=yes ;shift ;;
        --) shift ; break ;;
        *) echo "error!" ; exit 1 ;;
    esac
done

if [[ -n "$alpha" ]]
then
  echo "Doing alpha (charlie: $charlie)"
fi

if [[ -n "$bravo" ]]
then
  echo "Doing bravo (charlie: $charlie)"
fi

以下是您运行时会发生什么:

$ ./testscript -b -a -c
Doing alpha (charlie: yes)
Doing bravo (charlie: yes)

$ ./testscript -ab
Doing alpha (charlie: no)
Doing bravo (charlie: no)