如何设置bash脚本';stdin中的位置参数是什么?

如何设置bash脚本';stdin中的位置参数是什么?,bash,Bash,我有一个bash脚本,我希望从一个文件中读取它以设置它的参数。基本上,我的脚本按位置读取参数($1,$2,$3,等等) 我希望的选项之一是一个可以读入参数的配置文件(对于简单易用的配置),因此我希望set--命令可以工作(--可以覆盖参数)。但是,由于它们是在文件中定义的,因此我必须读入它并使用xargs传递它们: -c | --config) cat $2 | xargs set -- continue ;; 问题是xargs在--上安装了bug,所以我不知道如何实现这一点 注意

我有一个bash脚本,我希望从一个文件中读取它以设置它的参数。基本上,我的脚本按位置读取参数(
$1
$2
$3
,等等)

我希望的选项之一是一个可以读入参数的配置文件(对于简单易用的配置),因此我希望
set--
命令可以工作(
--
可以覆盖参数)。但是,由于它们是在文件中定义的,因此我必须读入它并使用
xargs
传递它们:

-c | --config)
  cat $2 | xargs set --
  continue
  ;;
问题是xargs在
--
上安装了bug,所以我不知道如何实现这一点

注意:我意识到我可以使用
源配置文件
并将其设置为变量;可能是最后的选择。我想知道我是否可以像上面那样做并简化文档

简化的示例脚本:

# foo.sh
echo "x y z" | xargs set --
echo $*

# Command line
$ bash foo.sh a b c
xargs: set: No such file or directory
a b c

xargs
无法执行
set
,因为:

  • set
    是shell内置命令,而不是外部命令
    xargs
    只知道如何执行命令。(一些具有相同名称的shell内置阴影命令,如
    printf
    true
    [
    。因此
    xargs
    可以执行这些命令,但语义可能与内置命令不同。)

  • 即使
    xargs
    可以执行
    set
    ,也不会有任何效果,因为
    xargs
    不会在shell的环境中运行;由
    xargs
    执行的每个命令都是一个单独的进程。因此,如果执行此操作,则不会出现错误:

     echo a b c | xargs bash -c 'set -- "${@}"' _
    
    但是它也不会做任何有用的事情。(用
    echo
    替换
    set
    ,您将看到它确实调用了命令。)


  • 如何从文件中读取参数。 首先,您需要回答这个问题:在文件中包含参数意味着什么?它们是单独的以空格分隔的单词,并且没有在任何参数中包含空格的机制吗?(这也是
    xargs
    在默认模式下工作所必需的,因此这不是一个完全不合理的假设,尽管它几乎肯定会在某个时候给您带来麻烦。)

    在这种情况下,您根本不需要
    xargs
    ;只需使用命令替换即可:

    set -- $(<file)
    

    同样,要注意管道进入
    mapfile
    ;它不起作用,原因与
    set

    xargs
    无法执行
    set
    相同,因为:

  • set
    是一个shell内置命令,而不是一个外部命令。
    xargs
    只知道如何执行命令。(一些shell内置的阴影命令具有相同的名称,例如
    printf
    true
    [
    。因此
    xargs
    可以执行这些命令,但语义可能与内置命令不同。)

  • 即使
    xargs
    可以执行
    set
    ,也不会有任何效果,因为
    xargs
    不会在shell的环境中运行;由
    xargs
    执行的每个命令都是一个单独的进程。因此,如果执行此操作,则不会出现错误:

     echo a b c | xargs bash -c 'set -- "${@}"' _
    
    但是它也不会做任何有用的事情。(用
    echo
    替换
    set
    ,您将看到它确实调用了命令。)


  • 如何从文件中读取参数。 首先,您需要回答这个问题:在文件中包含参数意味着什么?它们是单独的以空格分隔的单词,并且没有在任何参数中包含空格的机制吗?(这也是
    xargs
    在默认模式下工作所必需的,因此这不是一个完全不合理的假设,尽管它几乎肯定会在某个时候给您带来麻烦。)

    在这种情况下,您根本不需要
    xargs
    ;只需使用命令替换即可:

    set -- $(<file)
    

    同样,要小心管道插入
    mapfile
    ;它不起作用,原因与
    set

    不起作用是一样的。回答得很好。一个问题:“set是一个内置的shell,而不是一个外部命令。xargs只知道如何执行命令。”--这种差异的根源是什么?从xargs实现的角度来看,它为什么会在意?@jonah:
    xargs
    是一个外部命令(即一个独立的程序)。它不是shell的一部分,因此它无法以某种方式进入shell并调用shell实现中的函数,这就是shell内部的功能。
    xargs
    当然可以执行shell本身,但这将是一个新的、不同的shell。(我在回答中提到了这一点。)
    xargs
    可以运行与shell相同的外部命令,因为命令是真正的外部命令:它们是独立的独立程序。谢谢。我现在明白你说的了。回答得很好。一个问题:“set是一个shell内置命令,而不是外部命令。xargs只知道如何执行命令。”--这种差异的根源是什么?从xargs实现的角度来看,它为什么会在意?@jonah:
    xargs
    是一个外部命令(即一个独立的程序)。它不是shell的一部分,因此它无法以某种方式进入shell并调用shell实现中的函数,这就是shell内部的功能。
    xargs
    当然可以执行shell本身,但这将是一个新的、不同的shell。(我在回答中提到了这一点。)
    xargs
    可以运行与shell相同的外部命令,因为命令是真正的外部命令:它们是独立的独立程序。谢谢。我明白你刚才说的了
    mapfile -t args < file
    set -- "${args[@]}"