有没有什么简单的方法可以将命名参数传递(接收)给 shell 脚本?
例如,
my_script -p_out '/some/path' -arg_1 '5'
Run Code Online (Sandbox Code Playgroud)
并在内部my_script.sh将它们接收为:
# I believe this notation does not work, but is there anything close to it?
p_out=$ARGUMENTS['p_out']
arg1=$ARGUMENTS['arg_1']
printf "The Argument p_out is %s" "$p_out"
printf "The Argument arg_1 is %s" "$arg1"
Run Code Online (Sandbox Code Playgroud)
这在 Bash 或 Zsh 中可能吗?
我有一个将数据输出到 stdout ( command1 -p=aaa -v=bbb -i=4)的命令。输出行可以具有以下值:
rate (10%) - name: value - 10Kbps
Run Code Online (Sandbox Code Playgroud)
我想 grep 该输出以存储该“速率”(我想管道在这里会很有用)。最后,我希望该速率是第二个命令的参数值(假设command2 -t=${rate})
我这边看起来很棘手;我想更好地了解如何使用管道、grep、sed 等。
我已经尝试了很多这样的组合,但我对这些感到困惑:
$ command1 -p=aaa -v=bbb -i=4 | grep "rate" 2>&1 command2 -t="rate was "${rate}
Run Code Online (Sandbox Code Playgroud) 我遇到了这个脚本:
#! /bin/bash                                                                                                                                                                                           
if (( $# < 3 )); then
  echo "$0 old_string new_string file [file...]"
  exit 0
else
  ostr="$1"; shift
  nstr="$1"; shift  
fi
echo "Replacing \"$ostr\" with \"$nstr\""
for file in $@; do
  if [ -f $file ]; then
    echo "Working with: $file"
    eval "sed 's/"$ostr"/"$nstr"/g' $file" > $file.tmp 
    mv $file.tmp $file
  fi  
done
Run Code Online (Sandbox Code Playgroud)
他们使用的行的含义是什么shift?我认为脚本应该至少与参数一起使用,所以......?
考虑以下代码:
foo () {
    echo $*
}
bar () {
    echo $@
}
foo 1 2 3 4
bar 1 2 3 4
Run Code Online (Sandbox Code Playgroud)
它输出:
1 2 3 4
1 2 3 4
我正在使用 Ksh88,但我也对其他常见的 shell 感兴趣。如果您碰巧知道特定 shell 的任何特殊性,请务必提及它们。
我在 Solaris 上的 Ksh 手册页中找到了以下内容:
$* 和 $@ 的含义在不引用或用作参数赋值或文件名时是相同的。然而,当用作命令参数时,$* 等价于 ``$1d$2d...'',其中 d 是 IFS 变量的第一个字符,而 $@ 等价于 $1 $2 ....
我尝试修改IFS变量,但它不会修改输出。也许我做错了什么?
典型的 Unix/Linux 程序接受命令行输入作为参数计数 ( int argc) 和参数向量 ( char *argv[])。的第一个元素argv是程序名称 - 后跟实际参数。
为什么程序名称作为参数传递给可执行文件?是否有使用自己名称的程序示例(可能是某种exec情况)?
我有一个文件夹,里面有超过一百万个文件需要排序,但我真的什么也做不了,因为一直在mv输出这条消息
-bash: /bin/mv: Argument list too long
Run Code Online (Sandbox Code Playgroud)
我正在使用此命令移动无扩展名的文件:
mv -- !(*.jpg|*.png|*.bmp) targetdir/
Run Code Online (Sandbox Code Playgroud) 假设当我执行 ls 命令时,输出是:
file1 file2 file3 file4
Run Code Online (Sandbox Code Playgroud)
是否可以只显示特定的输出列,在这种情况下是 file2?我尝试了以下方法但没有成功:
echo ls | $2
Run Code Online (Sandbox Code Playgroud)
基本上我只想回显第二列,在这种情况下,我想回显:
file2
Run Code Online (Sandbox Code Playgroud) 前段时间我注意到curl作为命令行参数提供的用户名和密码没有出现在ps输出中(尽管它们当然可能出现在您的 bash 历史记录中)。
它们同样不会出现在/proc/PID/cmdline.
(不过,可以推导出组合的用户名/密码参数的长度。)
演示如下:
[root@localhost ~]# nc -l 80 &
[1] 3342
[root@localhost ~]# curl -u iamsam:samiam localhost &
[2] 3343
[root@localhost ~]# GET / HTTP/1.1
Authorization: Basic aWFtc2FtOnNhbWlhbQ==
User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Host: localhost
Accept: */*
[1]+  Stopped                 nc -l 80
[root@localhost ~]# jobs
[1]+  Stopped                 nc -l 80
[2]-  Running                 curl -u iamsam:samiam localhost &
[root@localhost ~]# ps -ef | grep curl
root      3343  3258  0 …Run Code Online (Sandbox Code Playgroud) 我想知道是否有通过 shebang 行 ( #!)将多个选项传递给可执行文件的通用方法。
我使用 NixOS,在我编写的任何脚本中,shebang 的第一部分通常是/usr/bin/env. 然后我遇到的问题是系统将其后的所有内容解释为单个文件或目录。
例如,假设我想编写一个脚本以bash在 posix 模式下执行。写shebang的天真方式是:
#!/usr/bin/env bash --posix
Run Code Online (Sandbox Code Playgroud)
但是尝试执行生成的脚本会产生以下错误:
/usr/bin/env: ‘bash --posix’: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我知道这篇文章,但我想知道是否有更通用和更清洁的解决方案。
编辑:我知道对于Guile脚本,有一种方法可以实现我想要的,在手册的第 4.3.4 节中记录:
 #!/usr/bin/env sh
 exec guile -l fact -e '(@ (fac) main)' -s "$0" "$@"
 !#
Run Code Online (Sandbox Code Playgroud)
这里的技巧是,第二行(以 开头exec)被解释为代码,sh但是,在#!...!#块中,作为注释,因此被 Guile 解释器忽略。
难道不能将此方法推广到任何解释器吗?
第二次编辑:在玩了一会儿之后,似乎对于可以从中读取输入的解释器,stdin以下方法可以工作:
#!/usr/bin/env sh
sed '1,2d' "$0" | bash --verbose --posix …Run Code Online (Sandbox Code Playgroud) 我的印象是,单个参数的最大长度在这里不是问题,而是整个参数数组的总大小加上环境的大小(仅限于ARG_MAX. 因此,我认为类似以下的事情会成功:
env_size=$(cat /proc/$$/environ | wc -c)
(( arg_size = $(getconf ARG_MAX) - $env_size - 100 ))
/bin/echo $(tr -dc [:alnum:] </dev/urandom | head -c $arg_size) >/dev/null
Run Code Online (Sandbox Code Playgroud)
这- 100足以解释 shell 和echo进程中环境大小之间的差异。相反,我收到了错误:
bash: /bin/echo: Argument list too long
Run Code Online (Sandbox Code Playgroud)
玩了一段时间后,我发现最大值小了一个完整的十六进制数量级:
/bin/echo \
  $(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) \
  >/dev/null
Run Code Online (Sandbox Code Playgroud)
当减一被删除时,错误返回。看似单个参数的最大值实际上是放置在参数数组中字符串末尾的空字节ARG_MAX/16的-1帐户。
另一个问题是,当参数重复时,参数数组的总大小可以接近ARG_MAX,但仍然不完全:
args=( $(tr -dc [:alnum:] </dev/urandom | head -c $(($(getconf ARG_MAX)/16-1))) )
for x in {1..14}; …Run Code Online (Sandbox Code Playgroud)