有没有办法重新排列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。
答案 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)