【问题标题】:String items in Variable / Parameter Expansion变量/参数扩展中的字符串项
【发布时间】:2019-02-05 20:22:50
【问题描述】:

我正在尝试使用变量,而不是在多个位置显式列出我的区域列表。

我意识到我可以下载所有文件,然后应用我正在寻找的文件。我觉得我应该能够做到这一点,我想这会让这有点学术练习。也许我的术语是关闭的,但我所做的大部分搜索都是基于整数的结果。下面的代码按原样工作......但我想用$zone_list 变量替换{ru,cn...}。这很容易成为文件扩展名或类型{jpg,php,htm,html} ...我是不是在这里偏离了基地,还是我应该以另一种方式考虑这个??

#!/bin/bash

ipset=/sbin/ipset
## zone_list="ru,cn,in,hk"
## zone_list="{ru,cn,in,hk}"

## wget -N http://www.ipdeny.com/ipblocks/data/countries/{$zone_list}.zone -P ~/testing/iptables/blacklists/zones/
wget -N http://www.ipdeny.com/ipblocks/data/countries/{ru,cn,in,hk}.zone -P ~/testing/iptables/blacklists/zones/

## $ipset -F
## $ipset -N -! blacklist hash:net maxelem 262144

for ip in $(cat ~/testing/iptables/blacklists/zones/{ru,cn,in,hk}.zone); do
   ##  $ipset -A blacklist $ip
   echo $ip
done

编辑:使用下面 Dzienny 的答案更新脚本

#!/bin/bash

ipset=/sbin/ipset
zone_list="{ru,cn,in,hk}"

eval "urls=(http://www.ipdeny.com/ipblocks/data/countries/${zone_list}.zone)"
wget -N "${urls[@]}" -P /srv/iptables-data/blacklists/zones/

## BLACKZONE RULE (select country to block and ip/range)
## $ipset -F
## $ipset -N -! blacklist hash:net maxelem 262144

eval "zonefiles=(/srv/iptables-data/blacklists/zones/${zone_list}.zone)"
for ip in $(cat "${zonefiles[@]}"); do
   ## $ipset -A blacklist $ip
   echo $ip
done

【问题讨论】:

  • 你的方法听起来很理智。在您第一次评论的 wget 中,您得到的是 {$zone_list} 而不是 ${zone_list}
  • 我应该提到我尝试了${}{$}{${}}甚至eval的各种组合,将大括号嵌入zone_list而不是。没有一个像我希望的那样奏效。
  • 这应该可行,使用第二个定义:zone_list="{ru,cn,in,hk}"。听起来您是 shell 新手,并且不完全了解 shell 替换。我建议制作一个极简脚本来设置一个变量并将echos 作为消息的一部分退出。实验看看它是如何工作的。之后,将 echo 替换为 for 循环和 echo 分段,并尝试在 forecho 中引用,以便了解引用的工作原理。另一种 shell 故障排除方法是使用 bash -x my_script 运行脚本,该脚本显示正在执行的行。

标签: linux bash variable-expansion brace-expansion


【解决方案1】:

Bash evaluatesbrace expansions 在扩展变量之前。这意味着如果您将大括号扩展字符串放入变量中并使用它,它将不会被解释,而是字符串将保持不变。

您可以使用内置的eval 来评估变量的内容。示例:

zones_exp="{ru,cn,in,hk}"
eval "urls=(http://www.ipdeny.com/ipblocks/data/countries/${zones_exp}.zone)"
wget -N "${urls[@]}" -P ~/testing/iptables/blacklists/zones/

或者你可以通过制作一个辅助函数来实现大括号扩展的去重,例如:

function insert_zones_exp() {
  expansion=("$1"{ru,cn,in,hk}"$2");
}

其中第一个参数是区域之前的部分和区域值之后的第二部分。

然后使用它:

insert_zones_exp "http://www.ipdeny.com/ipblocks/data/countries/" ".zone"
wget -N "${expansion[@]}" -P ~/testing/iptables/blacklists/zones/

【讨论】:

  • 这对wget 非常有效,两种方法都有效地做同样的事情......将字符串扩展为另一个变量,然后在命令中引用该变量。将此逻辑应用于cat for 循环,我仍然得到cat: /home/jason/testing/iptables/blacklists/zones/{ru,cn,in,hk}.zone: No such file or directory
  • 我的新循环看起来像eval "zonefiles=~/testing/iptables/blacklists/zones/${zone_list}.zone"
    for ip in $(cat "${zonefiles[@]}"); do
  • 您忘记了 () 将变量声明为数组。应该是eval "zonefiles=(~/testing/iptables/blacklists/zones/${zone_list}.zone)"
猜你喜欢
  • 2016-08-22
  • 1970-01-01
  • 2017-09-22
  • 1970-01-01
  • 2012-10-16
  • 1970-01-01
  • 2016-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多