天道酬勤,学无止境

bash

Test if a variable is read-only

问题 为了测试一个变量是否是只读的,有以下丑陋的黑客: # True if readonly readonly -p | egrep "declare -[:lower:]+ ${var}=" # False if readonly temp="$var"; eval $var=x 2>/dev/null && eval $var=\$temp 有没有更优雅的解决方案? 回答1 使用 subshel​​l 似乎有效。 具有本地和导出变量。 $ foo=123 $ bar=456 $ readonly foo $ echo $foo $bar 123 456 $ (unset foo 2> /dev/null) || echo "Read only" Read only $ (unset bar 2> /dev/null) || echo "Read only" $ $ echo $foo $bar 123 456 # Still intact :-) 重要的是,子shell 甚至可以挽救您的 RW(在这种情况下为 $bar)在当前 shell 中未设置。 用 bash 和 ksh 测试。 回答2 您还可以向变量添加一个空字符串,它仍然保留其值,但比使用子外壳更快,例如: foo+= 2>/dev/null || echo "Read only" 捕获为函数,它将是: is

2022-07-11 10:01:42    分类:技术分享    bash

Store parameter into variable with space

问题 考虑以下带有输出的命令: $ du -sm ~/Documents 458 /home/utilisateur/Documents $ du -sm ~/Documents --exclude='aa bb' --exclude='cc dd' 153 /home/utilisateur/Documents 我希望用这样的一个变量替换排除项,以获得相同的输出。 $ du -sm ~/Documents "$c" 但是,如果我使用以下设置变量,我失败了。 我测试过: $ c=--exclude='aa bb'\ --exclude='cc dd' $ du -sm ~/Documents "$c" 458 /home/utilisateur/Documents $ c="\"--exclude='aa bb' --exclude='cc dd'\"" $ du -sm ~/Documents $c 458 /home/utilisateur/Documents du: cannot access '"--exclude='\''aa': No such file or directory du: cannot access 'bb'\''': No such file or directory du: cannot access 'dd'\''"': No such file

2022-07-11 09:59:14    分类:技术分享    bash   variables   quotes

Shell: Ignore escape sequences while replacing a pattern

问题 我已经搜索了这个主题并看到了一些示例,但不知何故它对我不起作用。 我必须在 shell 脚本(包含文件路径和扩展名)的文件中用另一行替换一行。 我正在使用以下命令,但替换不起作用。 line='a|b|c|\\folder\file.txt' upd_line='a|b|c|\\folder\file.txt|d' sed -i 's#$line#$upd_line#g' sample.txt sample.txt 内容: HDR|date a|b|c|\\folder\file.txt 我预计第二行将替换为 $upd_line 的内容,但它保持不变。 请告知我做错了什么。 我在 bash 和 ksh 中尝试过,但没有成功。 回答1 这可能对您有用(GNU sed 和 bash): a='a|b|c|\\folder\file.txt' b='a|b|c|\folder\file.txt|d' qs(){ sed <<<$1 's/[][\\.*^$]/\\&/g';} sed "s/$(qs $a)/$(qs $b)/" file 这将创建一个函数qs ,它将变量字符串转换为 sed 正则表达式和替换中可接受的形式。 注意在 sed 命令周围使用双引号; 这允许 shell 插入 shell 变量和函数调用。 如果在您选择的终端中使用了 GNU readline,CMe

2022-07-11 09:57:59    分类:技术分享    bash   shell   unix   sed

Replace string starting with in between two lines using bash

问题 有没有办法在不使用循环的情况下使用 sed 替换整个文件中字符串的开头? 例如,我的源数据如下: str_address: 123 main street str_desc: Apt3 str_desc: 2nd floor str_city: new york str_desc: mailing address 现在,该文件将有数千个地址,但我希望任何时候出现在“ str_desc ”之后和“ str_address ”之前的“ str_city ”都被替换为“ str_address ”,但是出现在str_city之后的任何“ str_desc ”都保持不变。 期望的输出: str_address: 123 main street str_address: Apt3 str_address: 2nd floor str_city: new york str_desc: mailing address 我可以提取这些信息, cat file | awk '/str_city/{f=0} f; /str_address/{f=1}' 这使 str_desc: Apt3 str_desc: 2nd floor 但是我无法将第一个“ str_desc ”更改为“ str_address ”。 回答1 您的awk提取代码中几乎拥有完整的解决方案: awk '/str_city/{f

2022-07-11 09:54:14    分类:技术分享    bash   shell   awk   sed

Update array passed by reference with BASH

问题 我想编写一个函数,它接受一个数组变量名并更新内容。 例如: ARRAY1=("test 1" "test 2" "test 3") toUpper ARRAY1 for arg in "${ARRAY1[@]}"; do echo "arg=$arg" done # output arg=TEST 1 arg=TEST 2 arg=TEST 3 我做了一个粗略的尝试,这需要输入数组的副本。 使用间接引用,我能够创建输入变量的副本。 数组的副本用于获取元素的计数。 如果有更好的方法来做到这一点,请告诉我。 function toUpper() { local ARRAY_NAME=$1 local ARRAY_REF="$ARRAY_NAME[@]" # use an indirect reference to copy the array so we can get the count declare -a ARRAY=("${!ARRAY_REF}") local COUNT=${#ARRAY[@]} for ((i=0; i<$COUNT; i++)); do local VAL="${ARRAY[$i]}" VAL=$(echo $VAL | tr [:lower:] [:upper:]) echo "ARRAY[$i]=\"$VAL\"" eval "$ARRAY

2022-07-11 09:41:18    分类:技术分享    arrays   bash   pass-by-reference   indirection

Executing commands in batch inside Mininet

问题 给定一个 Mininet 网络,我想模拟流程,例如使用 iperf。 为此,我可以运行以下命令: h5 iperf3 -s -p 1337 & h6 iperf3 -s -p 1338 & h1 iperf3 -c h5 -n 10G -b 11M -p 1337 & h2 iperf3 -c h6 -n 10G -b 11M -p 1338 & 在 Mininet CLI 中, h1 、 h2 ... 表示 Mininet 拓扑上的主机。 如果 Mininet 命令以主机 ID 开头,则该命令将像在该主机上一样运行。 为方便起见,以后出现的任何 ID 都将替换为其 IP 地址。 这些命令有效,但我还没有找到自动化它们的方法。 我可以运行一个可以调用 bash 命令的 python 脚本,但是上面的命令会中断,因为上下文无法理解 mininet ID。 手动输入所有这些内容很烦人,即使是复制粘贴工作。 有没有办法向 mininet CLI 发送一批命令? 回答1 在 Mininet 文档中,可以使用脚本__init__ CLI 模式。 脚本的每一行都将在 CLI 中执行,无需停止用户输入。 粗略浏览本文档会发现 CLI 用于解释和执行命令的各个方法。 这是一个例子: myScript = "genTraffic.sh" CLI(net, script=myScript) #

2022-05-17 05:29:27    分类:技术分享    bash   mininet

sudo: command not found while using plink

问题 嗨,我创建了一个批处理文件(run.bat) ,执行后借助plink将我连接到 UNIX 服务器。 但是问题从这一点开始,我必须在连接到我的服务器后执行一个脚本,该脚本包含一个命令sudo -l 。 执行后,我收到主题中提到的错误,任何人都可以帮助我解决这个问题吗? 批处理文件-: "C:\Program Files\PuTTY" plink -ssh -pw Tos@12Ts w44dvftyw@caa1607UX009.wvd.abcd.net /opt/sieb/w44dvftyw/run.sh 脚本文件(run.sh)-: #!/bin/bash sudo -l 它说 sudo:找不到命令 但是当我在 UNIX 服务器上正常运行我的脚本时,它运行没有问题。 我在这里缺少什么以使其以这种方式工作,请提供帮助。 回答1 诸如~/.profile或~/.bash_profile之类的脚本负责设置当前用户的PATH仅在登录 shell 上运行。 运行sh -c 'somescript' (由ssh host 'somescript'执行)既不是登录 shell,也不是交互式 shell; 因此,它不会从此类脚本中受益。 这意味着以这种方式运行的命令可能不存在对PATH的添加(在您的情况下为/usr/local/bin )。 在您的选择中: 将您想要的 PATH

2022-05-17 05:28:13    分类:技术分享    bash   unix

LFTP file prefix while is being downloaded

问题 回答1 终于找到了答案: 需要以下额外参数: set xfer:use-temp-file yes set xfer:temp-file-name *.lftp

2022-05-17 02:52:17    分类:技术分享    bash   lftp

syntax error: unexpected end of file when running source

问题 我一直在尝试从 Xilinx 安装中获取此脚本,但它输出错误。 源 /opt/Xilinx/14.7/ISE_DS/settings32.csh # Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved. set SETTINGS_FILE=.settings32.csh set XIL_SCRIPT_LOC="/opt/Xilinx/14.7/ISE_DS" if ( $# != 0 ) then # The first argument is the location of Xilinx Installation. # Don't detect the installation location. set XIL_SCRIPT_LOC="$1" else # XIL_SCRIPT_LOC should point to script location set XIL_SCRIPT_LOC_TMP_UNI=`echo $_ | cut -d" " -f 2` set XIL_SCRIPT_LOC_TMP_UNI_TAIL=${XIL_SCRIPT_LOC_TMP_UNI:t} set XIL_SCRIPT_LOC_TMP_UNI=${XIL_SCRIPT_LOC_TMP_UNI:h} if ( "$XIL

2022-05-17 00:55:05    分类:技术分享    bash   xilinx

SSH to EC2 instance using boto on private IP through bastion server

问题 我正在尝试使用boto在 EC2 实例上执行一些 bash 脚本。 Boto 提供了一种通过公共 IP 连接到 EC2 实例的方式,但在我的情况下,这些实例只有私有 IP。 在这些实例上完成 SSH 的方式是使用一个主机,该主机可以使用私有 IP(堡垒主机)在所有实例上进行 SSH。 以下是连接到公共 IP 上的实例的脚本: s3_client = boto3.client('s3') s3_client.download_file('mybucket','key/mykey.pem', '/tmp/mykey.pem') k = paramiko.RSAKey.from_private_key_file("/tmp/mykey.pem") c = paramiko.SSHClient() c.set_missing_host_key_policy(paramiko.AutoAddPolicy()) host=event print "Connecting to " + host c.connect( hostname = host, username = "ec2-user", pkey = k ) 如果我们想通过具有公共 IP PPPP的堡垒主机连接,如果host具有私有 IP 而不是公钥,如何连接到实例 回答1 如果您的要求是触发在 Amazon EC2

2022-05-17 00:50:12    分类:技术分享    bash   amazon-web-services   ssh   amazon-ec2   boto3