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
    • 最新
    • 标签
主页 / unix / 问题 / 561695
Accepted
Geoff
Geoff
Asked: 2020-01-13 02:25:14 +0800 CST2020-01-13 02:25:14 +0800 CST 2020-01-13 02:25:14 +0800 CST

嵌套的 shell 脚本不适用于列表变量

  • 772

我创建了以下两个最小的 shell 脚本......

测试1

#!/usr/bin/env bash

letterList=$1

for letter in $letterList
do
    echo $letter
done

还有一秒钟

测试2

#!/usr/bin/env bash

letterList=$1

test1 $letterList

当我执行时,test1 'A B C'我得到了所需的输出,A然后B是C.

但是当我执行时,test2 'A B C'我希望test1 'A B C'会发生,但实际输出仅为A.

所以看起来嵌套变量列表似乎没有被读取——换句话说,正在执行的是test1 A.

发生了什么事,我怎样才能达到预期的结果?

PS:如果相关的话,我正在使用 OS X。

shell-script arguments
  • 3 3 个回答
  • 163 Views

3 个回答

  • Voted
  1. Kusalananda
    2020-01-13T02:46:26+08:002020-01-13T02:46:26+08:00

    您的代码中没有列表变量。你有一个字符串。

    调用test1使用未引用的扩展$letterList。这将使 shell 将其值拆分为空格、制表符和换行符上的多个单词(默认情况下),并且每个单词都将进行文件名通配符(如果它们包含文件名通配符)。结果单词test1作为单独的参数传递给。

    在test1中,您只需将这些参数中的第一个放入letterList.

    如果要将字符串按$letterList原样传递给test1from test2,则需要在调用中将其扩展双引号:

    test1 "$letterList"
    

    顺便说一句,您依赖于 shell 执行$letterList循环中的值拆分test1(与导致您的问题的机制相同),但您永远不会保护代码免受意外执行文件名通配(使用 eg 测试您的脚本test2 "A B C *"以了解我的意思) .


    如果要传递列表而不是单个字符串,请test2使用列表而不是字符串调用:

    test2 A B C "Hello World" "* *"
    

    然后,在 中test2,将参数传递给test1:

    #!/bin/sh
    
    test1 "$@"
    

    在这里,"$@"将扩展为位置参数列表(脚本的参数),每个单独的参数都被引用。这意味着Hello World在对 的调用中不会将参数 like 拆分为多个参数test1,并且字符串* *也不会拆分为两个,并且不会发生文件名通配。

    在test1中,迭代参数:

    #!/bin/sh
    
    for arg in "$@"; do
        printf '%s\n' "$arg"
    done
    

    或者

    #!/bin/sh
    
    for arg do
        printf '%s\n' "$arg"
    done
    

    ...或者,如果您只想打印参数,只需

    #!/bin/sh
    
    printf '%s\n' "$@"
    

    我一直用作/bin/sh外壳,因为这里没有任何特定于bash.

    • 3
  2. Best Answer
    kaylum
    2020-01-13T02:46:13+08:002020-01-13T02:46:13+08:00

    运行时./test2 'a b c'我们得到:

    $1=a b c
    

    所以最后一行变成:

    test1 a b c
    

    运行时test1我们得到:

    $1=a
    $2=b
    $3=c
    

    也就是说,给定的 argstest1没有用引号括起来,因此它们变成了三个 args 而不是一个。

    要传递test1单个参数,只需将变量括在双引号中。也就是说,将最后一行替换为test2:

    ./test1 "$letterlist"
    

    请注意,我还添加./了提供可执行文件的路径,因为.在$PATH.

    • 1
  3. G-Man Says 'Reinstate Monica'
    2020-01-27T12:27:15+08:002020-01-27T12:27:15+08:00

    目前尚不清楚您的实际目标是什么。您唯一清楚地说的是您要test2 'A B C' 输出A,B并且 C在三个单独的行上。

    这是一个不同的解决方案,可以为您提供该结果。一般来说,它似乎给出与 kaylum 的 answer相同的输出。

    • 保持test2不变。
    • 更改test1如下:

      #!/bin/sh
      
      for letter in $*
      do
          printf '%s\n' "$letter"
      done
      

      这自然会改变test1. 它现在查看它的所有论点,而不仅仅是$1. 所以将 在六个单独的行上test1 'A B C' 'D E F'输出A, B, C, D, Eand  (而不是仅仅, and  )。FABC

    我们通常不鼓励使用 ,$*因为它将包含空格的字符串分成单独的单词。例如,"lazy dog"会变成两个词(参数)。但这似乎正是您想要的行为。

    printf比echo文件名以-或包含\. 这已经在这个网站上详细讨论过;如果您想了解更多信息,只需搜索即可。

    • 0

相关问题

  • 在awk中的两行之间减去相同的列

  • 打印文件行及其长度的脚本[关闭]

  • 通过命令的标准输出以编程方式导出环境变量[重复]

  • 按分隔符拆分并连接字符串问题

  • MySQL Select with function IN () with bash array

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