标签: parameter-expansion

如何执行存储在变量中的命令?

调用存储在变量中的某些命令的正确方法是什么?
1和2之间有什么区别吗?

#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
Run Code Online (Sandbox Code Playgroud)

unix shell parameter-expansion

78
推荐指数
2
解决办法
13万
查看次数

如何在Fish shell中提取子串?

我得到以下变量:

set location "America/New_York"
Run Code Online (Sandbox Code Playgroud)

并希望使用shell语法仅显示/(斜杠)之前的部分.fish

预期结果

美国

Bash相当于

使用bash,我只是使用参数扩展:

location="America/New_York"
echo ${location##*/}"
Run Code Online (Sandbox Code Playgroud)

我怎么做到这一点fish

substring fish parameter-expansion

11
推荐指数
1
解决办法
3484
查看次数

Bash:如何使用运算符参数扩展$ {parameter @ operator}?

我用谷歌搜索并尝试了很多东西,从来没有任何东西可以使用$ {parameter @ operator}.我找到的只是更多链接到相同的文档.因此,我认为通过实际例子得到正确答案对其理解非常有帮助.

文件说:

$ {参数@操作}

扩展可以是参数值的变换,也可以是参数本身的信息,具体取决于运算符的值.每个运营商都是一个字母:

Q
扩展是一个字符串,它是以可以重复用作输入的格式引用的参数值.

它还说引用:

3.1.2引用
引用用于删除shell中某些字符或单词的特殊含义.

所以我的理由是这个(特殊字符$)的输出:

a="To be reused as an input string, \$0 needs to be quoted"
echo ${a@Q}
Run Code Online (Sandbox Code Playgroud)

应该是这个(在""之间,'\'被删除,所以需要再次引用作为输入):

To be reused as an input string, \$0 needs to be quoted
Run Code Online (Sandbox Code Playgroud)

但我得到:

bash: ${a@Q}: bad substitution
Run Code Online (Sandbox Code Playgroud)

我尝试了不同的组合:

${a@q}, "${a@Q}", a='To be reused as an input string, $0 needs to be quoted'
Run Code Online (Sandbox Code Playgroud)

无济于事.

实际上,我尝试使用的任何运算符总是会产生错误的替换错误.这些似乎是bash的非常模糊的特征.我已经从这篇文章中省略了大约半个小时的尝试,每个人都比以前更加扭曲!

bash quoting operator-keyword parameter-expansion

9
推荐指数
2
解决办法
1172
查看次数

附加到csh中可能尚不存在的环境变量的简单方法

我试图在我的PERL5LIB环境变量的末尾附加一个路径,但我不确定这个变量是否总是存在.如果它不存在,我想简单地将它初始化为我试图追加的值.

这是一个有效的例子:

if ( $?PERL5LIB ) then
    setenv PERL5LIB ${PERL5LIB}:/some/other/path
else
    setenv PERL5LIB /some/other/path
endif
Run Code Online (Sandbox Code Playgroud)

虽然这有效,但它仍然看起来很笨重,因为我必须基本上写两次同一行.我想做的是提出一个更有效的单线解决方案(可能使用参数扩展).

有没有办法将其合并为一条线?(或者多行不涉及多次写出"/ some/other/path")


例如,这可以在bash中完成:

export PERL5LIB=${PERL5LIB:+${PERL5LIB}:}/some/other/path
Run Code Online (Sandbox Code Playgroud)

csh environment-variables login-script parameter-expansion

9
推荐指数
1
解决办法
2194
查看次数

这个shell语法的机制:$ {1: - $(</ dev/stdin)}

我最近遇到了这个非常简洁的语法,在创建bash可以接受来自STDIN的参数或流的函数的上下文中(即可以通过管道传递).从表面上看,我理解这里发生了什么,但我想更多地解释一下这是如何工作的实际机制.

这是语法(根据标题): ${1:-$(</dev/stdin)}

在上下文中,可以将其用作:

log(){
 echo -e >&1 "INFO: ${1:-$(</dev/stdin)}"
}
Run Code Online (Sandbox Code Playgroud)

允许以下用法:

$ log foo
INFO: foo
Run Code Online (Sandbox Code Playgroud)

或者,您也可以这样做

mv -v foo.ext bar.ext | log
INFO: renamed 'foo.ext' -> 'bar.ext'
Run Code Online (Sandbox Code Playgroud)

这很棒,因为它是我看到的用于启用参数和管道功能的单一最简洁的方法bash(不幸的是我忘记了我现在遇到它的地方).

现在,我理解(或者我认为我理解),这里发生的大部分事情至少表面上看,但我会更加理解.这是我如何解释它,然后是我剩下的问题:

${1:-$(</dev/stdin)}

  • ${1} 显然是函数接受的默认参数
  • ${1:-x}是否为变量/大括号扩展'后退'到字符串'x',$1否则为空(或未设置?).在这种情况下,回退到STDIN进程子.
  • $()显然是一个进程命令替换
  • 最后,</dev/stdin显然是标准输入的重定向,它允许管道工作.

这基本上说如果$1不是由参数填充,则回退到使用STDIN - 我在概念上很满意.

所以这是我的问题:

  1. 我从来没有<进程命令替换中看到redirect(),没有在它之前的实际命令(例如$(cat < somefile.ext)).那么当进程命令替换收到重定向而没有其他命令要调用时,实际发生了什么(细节)?
  2. 为什么有必要在进程命令替换中包装STDIN重定向?(实际上,当我写这个时,它发生在我身上,我没有测试它,但我会保持简单).
  3. 这样安全吗?我已经将它与多线STDIN一起使用了,到目前为止还没有破坏.这可能会降到哪里(如果在哪里?).

bash stdin command-substitution parameter-expansion

9
推荐指数
1
解决办法
210
查看次数

正则表达式匹配行尾 $ 在 Bash 脚本中不起作用

我正在尝试在 bash 脚本中执行一个简单的正则表达式语句,该语句将匹配并替换单词的结尾。下面是我正在尝试做的。

wordh > word:’
Run Code Online (Sandbox Code Playgroud)

下面是我正在使用的代码。

#!/bin/bash
STAT=${STAT/h$/:’}
Run Code Online (Sandbox Code Playgroud)

我不熟悉 bash 脚本,我认为它与 bash 有关系,$因为它用于标记变量。我试图逃避它以及/在它之后添加另一个。当我删除$它时(不检查单词的结尾)。

regex bash eol parameter-expansion

6
推荐指数
1
解决办法
972
查看次数

数组上的 shell 参数扩展

假设我将一些数据读入 Bash 数组:

$ IFS=" " read -a arr <<< "hello/how are/you iam/fine/yeah"
Run Code Online (Sandbox Code Playgroud)

现在,我想打印/数组中每个元素的第一个切片字段。

我所做的是循环遍历元素并使用 shell 参数扩展从第一个元素中删除所有内容/

$ for w in "${arr[@]}"; do echo "${w%%/*}"; done
hello
are
iam
Run Code Online (Sandbox Code Playgroud)

但是,sinceprintf允许我们在单个表达式中打印数组的全部内容:

$ printf "%s\n" "${arr[@]}"
hello/how
are/you
iam/fine
Run Code Online (Sandbox Code Playgroud)

...我想知道是否有一种方法可以${w%%/*}在使用时使用 shell 参数扩展printf,而不是循环遍历所有元素并对每个元素执行此操作。

arrays bash parameter-expansion

6
推荐指数
1
解决办法
5055
查看次数

负参数在参数扩展中如何在extglob中工作

问题

的行为

!(pattern-list)
Run Code Online (Sandbox Code Playgroud)

特别是在参数扩展中使用时,我的工作方式不正常

${parameter/pattern/string}
Run Code Online (Sandbox Code Playgroud)

输入

a="1 2 3 4 5 6 7 8 9 10"
Run Code Online (Sandbox Code Playgroud)

测试用例

$ printf "%s\n" "${a/!([0-9])/}"
[blank]
#expected 12 3 4 5 6 7 8 9 10

$ printf "%s\n" "${a/!(2)/}"
[blank]
#expected  2 3 4 5 6 7 8 9 10

$ printf "%s\n" "${a/!(*2*)/}"
2 3 4 5 6 7 8 9 10
#Produces the behaviour expected in previous one, not sure why though

$ printf "%s\n" "${a/!(*2*)/,}"
,2 3 4 5 6 …
Run Code Online (Sandbox Code Playgroud)

bash extglob parameter-expansion

6
推荐指数
1
解决办法
158
查看次数

用纯 bash 创建 URL 友好的 slug?

我追求一个纯粹的 bash 解决方案来“slugify”一个变量,这不像我的那么难看。

slugify : 小写,缩短为 63 字节,除 0-9 和 az 之外的所有内容都替换为 -。没有前导/尾随 -。结果是一个适合在 URL 主机名和域名中使用的字符串。输入很可能是一系列带有不想要的字符的单词,例如:

'Effrafax_mUKwT'uP7(Garkbit<\1}@NJ"RJ"Hactar*S;-H%x.?oLazlarl(=Zss@c9?qick.:?BZarquonelW{x>g@'k'

其中一个 slug 看起来像:'effrafax-mukwt-up7-garkbit-1-njrjhactar-shx-olazlarl-zss-c9-q'

slugify () {
  next=${1//+([^A-Za-z0-9])/-}
  next=${next:0:63}
  next=${next,,}
  next=${next#-}
  next=${next%-}
  echo $next
}
Run Code Online (Sandbox Code Playgroud)

另外为什么不${next//^-|-$}去掉前缀和后缀'-'?其他建议?

bash slug parameter-expansion

6
推荐指数
2
解决办法
1973
查看次数

为什么这个参数扩展替换在 bash 4.2 中失败但在 5.1 中有效?

我正在尝试将一些代码从 bash 5.1 移植到 4.2.46。一个尝试从特定格式的字符串中去除颜色代码的函数停止工作。

text这是这种格式的示例字符串。我为此打开了扩展通配符。

text="$(printf -- "%b%s%b" "\[\e[31m\]" "hello" "\[\e[0m\]")"
shopt -s extglob
Run Code Online (Sandbox Code Playgroud)

在 bash 5.1 中,此参数扩展可删除所有颜色代码和转义字符

bash-5.1$ echo "${text//$'\[\e'\[/}"
31m\]hello0m\]
bash-5.1$ echo "${text//$'\[\e'\[+([0-9])/}"
m\]hellom\]
bash-5.1$ echo "${text//$'\[\e'\[+([0-9])m$'\]'/}"
hello
Run Code Online (Sandbox Code Playgroud)

在 bash 4.2.46 中,当我构建参数扩展时,我开始出现不同的行为。

bash-4.2.46$ echo "${text//$'\[\e'\[/}"
\31m\]hello\0m\]
bash-4.2.46$ echo "${text//$'\[\e'\[+([0-9])/}"
\[\]hello\[\]  ## no longer matches because `+([0-9])` doesn't follow `\[`
Run Code Online (Sandbox Code Playgroud)

差异来自于这一行:echo "${text//$'\[\e'\[/}"

bash-5.1:    31m\]hello0m\]
bash-4.2.46: \31m\]hello\0m\]
Run Code Online (Sandbox Code Playgroud)

显示内容如下printf "%q" "${text//$'\[\e'\[/}"

bash-5.1:    31m\\\]hello0m\\\]
bash-4.2.46: \\31m\\\]hello\\0m\\\]
Run Code Online (Sandbox Code Playgroud)

4.2.26 中的额外内容从哪里来\

即使当我尝试删除它时,模式也会停止匹配:

bash-5.1:    31m\]hello0m\]
bash-4.2.46: \31m\]hello\0m\]
Run Code Online (Sandbox Code Playgroud)

我猜测可能存在与参数扩展、反斜杠转义和扩展通配符相关的错误。

我的目标是编写适用于 …

bash glob parameter-expansion

6
推荐指数
2
解决办法
209
查看次数