AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / user-142469

Richie Thomas's questions

Martin Hope
Richie Thomas
Asked: 2022-10-30 09:21:50 +0800 CST

bash参数扩展-如何用“字符串”替换“模式”的*所有*实例?

  • 7

我已经阅读了GNU 的“Shell Parameter Expansion”文档,给出了以下语法:

${parameter//pattern/string}

该模式被扩展以产生一个模式,就像在文件名扩展中一样。参数被扩展,模式 与其值的最长匹配被替换为字符串......如果有两个斜杠分隔参数和模式......,所有匹配的模式都被替换为字符串。

鉴于上面的短语“模式的所有匹配项都替换为字符串”,我希望在一个操作中一次将模式的多个实例全部替换为字符串 ,类似于标志如何与全局搜索和替换一起使用正则表达式中的命令。/g

我有一段开源代码(一个名为 的函数remove_from_path),其实现如下:

remove_from_path() {
  local path_to_remove="$1"
  local path_before
  local result=":${PATH//\~/$HOME}:"
  local counter=0
  while [ "$path_before" != "$result" ]; do
    counter+=1
    echo "counter: $counter"
    path_before="$result"
    result="${result//:$path_to_remove:/:}"
  done
  result="${result%:}"
  echo "${result#:}"
}

原始代码不包含该变量——我添加了该变量以检查循环将执行counter多少次迭代。while

正如我们所看到的,该行result="${result//:$path_to_remove:/:}"使用了 GNU 文档中提到的相同的双正斜杠语法。鉴于此,我希望while循环只会执行一次,因为path_to_remove应该result一次性删除所有实例。

然而,情况似乎并非如此。在bashshell ( version 3.2.57) 中,我将 my 更新$PATH为以下内容:

bash-3.2$ PATH="/foo/bar/baz:/foo/bar/baz:/foo/bar/baz:buzz"

然后我将上述函数复制/粘贴到我的 shell 中,然后运行它。我看到以下内容:

bash-3.2$ remove_from_path "/foo/bar/baz"
counter: 01
counter: 011
counter: 0111
buzz

请忽略计数器的递增没有按我预期的方式工作的事实,因为我们仍然可以看到while循环的 3 次执行。如果${parameter//pattern/string}双正斜杠语法确实用字符串替换了所有匹配的模式,为什么没有在循环的一次迭代中完成呢?为什么我们需要 3 次迭代?while

bash
  • 3 个回答
  • 80 Views
Martin Hope
Richie Thomas
Asked: 2022-10-07 07:24:14 +0800 CST

设置了 `noclobber` 选项时,`/dev/null` 的处理方式是否与其他文件不同?

  • 6

作为一个实验,我尝试运行set -o noclobber然后运行echo foo > /dev/null​​. 我能够这样做;没有出现错误:

bash-3.2$ set -o noclobber
bash-3.2$ echo "foo" > /dev/null
bash-3.2$ echo "bar" > /dev/null
bash-3.2$ echo "baz" > /dev/null

但是,当我对之前创建的文件尝试相同的操作时,我看到了预期的错误:

bash-3.2$ touch bar.txt
bash-3.2$ echo "bar" > bar.txt
bash: bar.txt: cannot overwrite existing file

noclobber对待文件的方式与对待其他文件的方式不同吗/dev/null?

注意:我理解它为什么会以这种方式运行(即因为它的性质和目的是什么),但我在这里/dev/null没有看到任何与此相关的文档。我想这可能是一个未记录的功能,或者(可能更有可能)我只是错过了文档?

bash
  • 1 个回答
  • 594 Views
Martin Hope
Richie Thomas
Asked: 2022-09-21 07:55:51 +0800 CST

为什么有必要在这个 `bash` 脚本中检查 `awk`?

  • 0

我正在阅读“rbenv”Ruby 版本管理器的开源代码,我看到该库的命令之一检查是否已安装gawkawk:

  awk="$(type -p gawk awk 2>/dev/null | head -n1)"
  if [ -z "$awk" ]; then
    echo "rbenv: cannot find awk" >&2
    return 1
  fi

但我还在bash文件的最顶部看到了一个 shebang:

#!/usr/bin/env bash

起初我认为awk如果 shebang 保证我们在bash脚本中运行,我们应该能够假设我们可以运行,但后来我发现这awk是一个 UNIX 命令,而不是 shell 命令,并且我们可能正在运行这个脚本非 UNIX 系统(如 Windows)上的文件。从这个链接,我推断出非 UNIX 系统gawk最常见的风格。awk

我是否正确,我们不能假设awk已安装的原因是因为它是一个 UNIX 命令,而且我们可能不在 UNIX 机器上运行?为什么我们还要检查,gawk因为它是我们期望在尚未awk安装的系统(即非 UNIX 系统)上找到的最有可能的替代品?

shell awk
  • 2 个回答
  • 62 Views
Martin Hope
Richie Thomas
Asked: 2022-09-19 08:57:55 +0800 CST

传递给“sed -e”的这个脚本的功能是什么?

  • 0

TL;DR- 下面的模式中发生了很多事情sed,我不确定离散的部分是如何组合成一个整体命令的。


重击版本:GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin21)

我正在通过逐个文件阅读 RBENV 代码库文件来学习 shell 脚本,并且我遇到了rbenv-help包含此函数定义的文件:

extract_initial_comment_block() {
  sed -ne "
    /^#/ !{
      q
    }

    s/^#$/# /

    /^# / {
      s/^# //
      p
    }
  "
}

我看到如何在代码中进一步调用此函数,所以我知道它的第一个 arg 是文件名:

extract_initial_comment_block < "$filename" | collect_documentation

从这里我可以看到由“$filename”表示的文件被作为标准输入提供给sed命令。就我的问题而言,连锁功能“collect_documentation”是无关紧要的。

我还从函数的名称中得知,它的目的是获取这样的文件,并返回其摘要和使用注释,即链接文件的第 2-14 行。但是,我还没有测试过这个理论,所以我可能不是 100% 正确的。

此外,我从这个 StackExchange 答案中知道,标志的目的-e是告诉sed将后续字符串解释为命令(或由换行符分隔的命令集合?)。因此,它的主体看起来extract_initial_comment_block包含 3 个单独的脚本,sed以便按顺序进行解释。相同的 StackExchange 答案说{...}用于将命令组合在一起,但我不确定这是否是这个正则表达式(这些正则表达式?)中发生的事情。

据我所知,这里有 3 个脚本sed:

    /^#/ !{
      q
    }
    s/^#$/# /
    /^# / {
      s/^# //
      p
    }

但是,即使在这些脚本中的每一个中,都使用了一些我无法识别的模式(例如^#和),即使在利用了Linux Data Project之类的资源之后也是如此。似乎有很多动人的部分,我不确定每个脚本是如何组合成成品的。!{ q }

我试图以尽可能清晰的方式走过我的思考过程。到目前为止,我的思路正确吗?如果不是,我在哪里偏离了航线?如果是,我如何推断传递给的每个命令的含义sed?

bash regular-expression
  • 1 个回答
  • 42 Views
Martin Hope
Richie Thomas
Asked: 2022-09-18 16:02:48 +0800 CST

为什么 `exec -a` 不能按我预期的方式工作?

  • 4

我正在阅读exec以及如何使用该-a标志。SS64文档似乎准确;他们说:

执行:

执行命令

句法:

exec [-cl] [-a name] [command [arguments]]

选项:

-c   Causes command to be executed with an empty environment.

-l   Place a dash at the beginning of the zeroth arg passed to command.
     (This is what the login program does.)

-a   The shell passes name as the zeroth argument to command.

为了测试这一点,我编写了两个脚本,一个名为foo/baz,一个名为foo/buzz:

#!/usr/bin/env bash
# foo/baz

exec -a blah ./foo/bar 1 2
#!/usr/bin/env bash
# foo/buzz

exec ./foo/bar 1 2

这些脚本中的每一个都运行相同的子脚本 ,foo/bar它执行以下操作:

#!/usr/bin/env bash

echo "Hello world"
echo "0: $0"
echo "1: $1"
echo "2: $2"

我的目标是看看-a对第 0 次和随后的论点有什么影响。如果-a导致第 0 个参数更改为您传递给-a标志的参数,那么当我运行时我希望第 0 个参数foo/baz是blah,因为这就是我传递给-a. 但是,当我运行脚本时,两种情况下的输出都是相同的:

~/Workspace/OpenSource (master)  $ ./foo/baz 
Hello world
0: /Users/richiethomas/Workspace/OpenSource/foo/bar
1: 1
2: 2
~/Workspace/OpenSource (master)  $ ./foo/buzz
Hello world
0: /Users/richiethomas/Workspace/OpenSource/foo/bar
1: 1
2: 2

难道我做错了什么?还是我的期望不正确?

另外,一个相关的问题——覆盖第 0 个参数的用例是什么,而不是仅仅通过 $1、$2、$3 等访问任何传入的参数?

bash
  • 3 个回答
  • 618 Views
Martin Hope
Richie Thomas
Asked: 2022-09-12 14:44:42 +0800 CST

鱼壳 - 这种语法有什么问题?

  • 0

我有一个 bash 脚本,它cat是一个 heredoc 字符串,我在鱼壳中运行它,然后将它传递给一个source调用,如下所示:

~/foo/baz:

  1 #!/usr/bin/env bash
  2 
  3 cat << EOS
  4   function bar
  5     echo 'Hello world'
  6   end
  7 EOS

从鱼壳:

richiethomas@richie ~/foo (master) [126]> ./baz | source
richiethomas@richie ~/foo (master)> bar

Hello world

如上所示,这导致bar我运行时可以调用该函数./baz | source。

但是,当我将bar函数的实现更改为以下内容时出现错误:

  1 #!/usr/bin/env bash
  2 
  3 cat << EOS
  4   function bar 
  5     set myVar 5 
  6     switch $myVar 
  7       case 4 
  8         echo '4' 
  9       case 5 
 10         echo '5' 
 11       case '*' 
 12         echo 'Not found' 
 13     end 
 14   end
 15 EOS

当我尝试source这样做时,我收到以下错误:

richiethomas@richie ~/foo (master) [0|1]> ./baz | source
- (line 1): Missing end to balance this function definition
  function bar
  ^
from sourcing file -
source: Error while reading file '<stdin>'

当我将其直接粘贴到鱼壳中时,等效的函数 + switch 语句可以正常工作:

richiethomas@richie ~/foo (master) [0|1]> function bar
                                              set myVar 5
                                              switch $myVar
                                                  case 4
                                                      echo 'it is 4!'
                                                  case 5
                                                      echo 'it is 5!'
                                                  case '*'
                                                      echo 'not found'
                                              end
                                          end

richiethomas@richie ~/foo (master)> bar

it is 5!

我end在文件和复制/粘贴到 shell 中的代码中都有相同的语句数baz,所以我怀疑错误语句是红鲱鱼?如果是这样,我不知道真正的错误可能是什么。

我的目标是能够在 bash 脚本的 heredoc 字符串中构造一个 fish 函数,然后从 fish 脚本中获取该 bash 脚本,以便我可以调用该函数。我在这里哪里做错了?

fish
  • 1 个回答
  • 39 Views
Martin Hope
Richie Thomas
Asked: 2022-09-11 12:54:33 +0800 CST

Fish shell - 用于创建检查值数组的 switch 语句的语法

  • 1

我正在研究 RBENV 代码库,我看到在文件的第 116 行rbenv-init,创建了一个包含switch语句的函数。我的假设是我们检查变量的值是否是(复数)变量command中值数组的成员之一。commands如果是,我们执行 switch 语句的分支 1。否则,我们执行分支 2。

我想写一个简单的脚本来测试我的假设,所以我写了以下内容:

#!/usr/bin/env fish

set command "foo"

switch $command
case ${argv[*]} 
  echo "command in args"
case "*" 
  echo "command not found"
end

但是,当我运行此脚本时,出现以下错误:

$ ./foo bar baz

./foo (line 6): ${ is not a valid variable in fish.
case ${argv[*]} 
      ^
warning: Error while reading file ./foo

我期待评估一个包含andargv的数组,因为这是我提供给脚本的两个参数。我的语法与源代码(即)中第 117 行的语法相匹配。barbazcase ${commands[*]}

我在其中执行脚本的外壳是 zsh v5.8.1,但是我的 shebang 专门引用了“鱼”外壳,所以我认为我的外壳无关紧要。我已经安装了鱼 v3.5.1,fwiw。

fish
  • 1 个回答
  • 36 Views

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    模块 i915 可能缺少固件 /lib/firmware/i915/*

    • 3 个回答
  • Marko Smith

    无法获取 jessie backports 存储库

    • 4 个回答
  • Marko Smith

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    user12345 无法获取 jessie backports 存储库 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl 为什么大多数 systemd 示例都包含 WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve