天道酬勤,学无止境

sh

When does a sub shell inherits its parent shell env?

问题 回答1 子shell 总是从父shell 获取所有变量。 man bash会描述所有使用子shell的情况,主要有: command & command | command command | command和( command ) 所谓环境只包括环境变量( export variable ),并传递给每个子流程。 即使在调用bash -c command时,它也不是一个子 shell,而是一个全新的 bash 实例。 在这两种情况下,更改的值都不会传递回父进程。

2022-05-15 18:39:03    分类:技术分享    bash   shell   sh

How to get a password from a shell script without echoing

问题 我有一个脚本可以自动执行需要访问受密码保护的系统的过程。 通过接受用户密码作为参数的命令行程序访问系统。 我想提示用户输入他们的密码,将其分配给一个 shell 变量,然后使用该变量来构造访问程序的命令行(这当然会产生我将处理的流输出)。 我是 Bourne/Bash 中相当称职的 shell 程序员,但我不知道如何接受用户输入而不让它回显到终端(或者可能使用'*'字符回显它)。 有人能帮忙吗? 回答1 这是另一种方法: #!/bin/bash # Read Password echo -n Password: read -s password echo # Run Command echo $password read -s将为您关闭回声。 只需将最后一行的echo替换为您要运行的命令即可。 回答2 #!/bin/sh stty -echo printf "Password: " read PASSWORD stty echo printf "\n" 回答3 一个班轮: read -s -p "Password: " password 在 Linux(和 cygwin)下,这种形式适用于 bash 和 sh。 不过,它可能不是标准的 Unix sh。 有关更多信息和选项,请在 bash 中键入“帮助阅读”。 $ help read read: read [-ers] [-a

2022-05-15 06:30:23    分类:技术分享    bash   shell   scripting   sh

shell $@ variable assignment and iteration

问题 function f() { for arg; do echo "$arg" done } f 'hello world' 'second arg' '3rdarg' 这工作正常: hello world second arg 3rdarg 但是我什么时候将$@分配给某个变量,然后它就出错了: function f() { local args="$@" for arg in "$args"; do echo "$arg" done } 输出: hello world second arg 3rdarg 当我取消引用$args时,每个参数都被分成一个单词: hello world second arg 3rdarg 最后,我想知道是否有一种方法可以定义像 $@ 这样的变量。 任何回应将不胜感激。 回答1 function f() { local args=("$@") # values in parentheses for arg in "${args[@]}"; do # array expansion syntax echo "$arg" done }

2022-05-12 08:53:13    分类:技术分享    bash   shell   sh

In bash script, how to use function exit status in while loop condition

问题 #!/bin/sh check1() { return 1 } while [ check1 ] do echo $? check1 if [ $? -eq 0 ]; then echo "Called" else echo "DD" fi sleep 5 done 回答1 删除test命令 - 也称为[ 。 所以: while check1 do # Loop while check1 is successful (returns 0) if check1 then echo 'check1 was successful' fi done 从 Bourne 和 POSIX shell 派生的 shell 在条件语句之后执行命令。 一种看待它的方法是, while和if测试成功或失败,而不是 true 或 false(尽管true被认为是成功的)。 顺便说一句,如果你必须测试$? 显式地(通常不需要)然后(在 Bash 中) (( ))构造通常更易于阅读,如下所示: if (( $? == 0 )) then echo 'worked' fi 回答2 函数(或命令)执行返回的值存储在 $? 中,一种解决方案是: check1 while [ $? -eq 1 ] do # ... check1 done 一个更好更简单的解决方案可能是: while ! check1 do #

2022-05-09 20:33:10    分类:技术分享    linux   bash   shell   sh

scp: how to find out that copying was finished

问题 我正在使用 scp 命令将文件从一台 Linux 主机复制到另一台。 我在主机 1 上运行 scp 推荐并将文件从主机 1 复制到主机 2。 文件很大,复制它需要一些时间。 复制开始后,host2 上的文件立即出现。 即使复制仍在进行中,我也可以使用此文件执行所有操作。 是否有任何可靠的方法可以确定 host2 上的复制是否完成? 回答1 while ! inotifywait -e close $(dirname ${bigfile_fullname}) 2>/dev/null | \ grep -Eo "CLOSE $(basename ${bigfile_fullname})$">/dev/null do true done echo "File ${bigfile_fullname} closed" 回答2 在我的脑海中,您可以执行以下操作: touch tinyfile scp bigfile tinyfile user@host: 然后当出现tinyfile时就知道bigfile的传输完成了。 正如评论中所指出的,这假设scp将按照指定的顺序一个一个地复制文件。 如果您不信任它,您可以明确地一一进行: scp bigfile user@host: scp tinyfile user@host: 这种方法的缺点是您可能必须进行两次身份验证。 如果这是一个问题

2022-05-07 16:29:25    分类:技术分享    linux   bash   shell   sh   scp

How to get exact list of collections form mongo database in shell script

问题 我想从 mongo 数据库中获取集合名称列表。 因此,我在 shell 脚本中使用以下命令: 集合= mongo $dbName --eval "db.getCollectionNames()" 该命令的输出结果是 “MongoDB shell 版本:2.2.0 连接到:cm_v2 col1,col2,col3,col4” 我只想获取集合名称,例如:col、col2、col3、col4。 那么,我应该如何从结果中删除类似版本的输出。 回答1 如果你想获得一个可以迭代的集合数组,可以使用类似这样的东西(如果你在集合名称中有空格,这可能会咬你): collections=`echo "show collections" | mongo $dbName --quiet` for collection in $collections; do echo "$collection" done 这将返回一个带引号的 JSON 格式的名称列表,这对于 BASH 脚本并不是很有用 mongo $dbName --quiet --eval "db.getCollectionNames()" [ "collection1", "collection2" ] 回答2 collections=mongo $dbName --quiet --eval "db.getCollectionNames()"

2022-05-07 05:27:03    分类:技术分享    linux   mongodb   shell   sh

"if" statement won't work on Debian Linux

问题 我有一个 bash 脚本,其中包含以下“if”语句。 问题是我无法让它在 Debian 上运行(它在 Fedora 和 CentOS 上运行良好)。 if [ $1 == "--daily" ] # <--- line 116 then countDaily elif [ $1 == "--monthly" ] # <--- line 119 then countMonthly fi 运行后: sh /home/kris/countsc.sh --daily 我收到一个错误: /home/kris/countsc.sh: 116: [: --daily: unexpected operator /home/kris/countsc.sh: 119: [: --daily: unexpected operator 回答1 由于您使用的是sh而不是 bash,因此您应该使用单个等号=来进行字符串比较,而不是双等号== 。 此外,在测试语句中双引号引用变量也是一个好习惯(尽管此错误不是由不正确的引用引起的)。 比较应该是: if [ "$1" = "--daily" ] 和 elif [ "$1" = "--monthly" ] 回答2 据我所知,在这种情况下使用的test中没有双等号运算符。 如果要测试字符串是否相等,只需使用单个等号,如下所示: if [ $1 = "-

2022-05-06 11:59:04    分类:技术分享    linux   sh

How to hide displaying terminal command output

问题 当我运行这个命令时, sudo htpasswd -b /home/reynolds/.htpasswd admin admin 我正在终端中Updating password for user admin但我不想显示该输出。 所以我在谷歌搜索了一些并尝试使用以下命令。 sudo htpasswd -b /home/reynolds/.htpasswd admin admin 2>&1 sudo htpasswd -b /home/reynolds/.htpasswd admin admin > /dev/null 但我仍然在终端中获得该输出。请帮助避免在运行此命令时显示此类输出。 请给我建议,因为我是 shell 脚本的初学者。 谢谢。 回答1 > /dev/null 并且正常输出被抑制,但仍然显示错误 按照命令 > /dev/null 2>&1 一切,包括错误都被抑制 回答2 只需执行以下操作; sudo htpasswd -b /home/reynolds/.htpasswd admin admin > /dev/null 2>&1 应该隐藏一切! 回答3 您收到此错误的原因是sudo仅适用于参数列表中的第一个命令。 解决这个问题的方法是像这样封装你的命令,以 bash 为例: sudo bash -c "htpasswd -b /home/reynolds/

2022-05-06 06:20:14    分类:技术分享    bash   shell   sh

Today's date, minus X days in shell script

问题 我需要为今天的日期创建三个变量,分别代表年、月和日,减去 X 天。 对于这个问题,我将随机选择天数:222。 因此,如果: TodayYear=`date +%Y` TodayMonth=`date +%m` TodayDay=`date +%d` 我想要的是在此之前的 222 天。 222days_before_TodayYear=??? 222days_before_TodayMonth=??? 222days_before_TodayDay=??? 编辑:需要 222 个工作日而不是 222 个正常工作日。 回答1 对于 GNU date : date_222days_before_TodayYear=$(date --date="222 days ago" +"%Y") date_222days_before_TodayMonth=$(date --date="222 days ago" +"%m") date_222days_before_TodayDay=$(date --date="222 days ago" +"%d") 对于 BSD date : : 如果您使用的是 OS X 或 FreeBSD,请改用以下内容,因为 BSD 日期与 GNU 日期不同: date_222days_before_TodayYear=$(date -j -v-222d +"%Y"

2022-05-04 15:29:41    分类:技术分享    bash   sh

My mac osx launched plist won't run

问题 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.IMG.shed</string> <key>ProgramArguments</key> <array> <string>/Users/IMG/2012/Dropbox/Dev_2012/Java/sh_IMG.sh</string> </array> <key>StandardOutPath</key> <string>myjob.log</string> <key>StandardErrorPath</key> <string>myjob.log</string> <key>Debug</key> <true/> <key>RunAtLoad</key> <true/> <key>StartInterval</key> <integer>60</integer> </dict> </plist> 回答1 我首先想到的是该进程没有创建标准输出日志文件的权限

2022-05-03 14:08:23    分类:技术分享    macos   plist   sh   launchd