Questions tagged «shell-script»

有关shell脚本,由shell解释的可执行文件(bash,zsh等)的问题。

4
如何在bash中移动数组值
我们要构建6个挂载点文件夹作为示例 /data/sdb /data/sdc /data/sdd /data/sde /data/sdf /data/sdg 所以我们使用数组编写了这个简单的bash脚本 folder_mount_point_list="sdb sdc sdd sde sdf sdg" folderArray=( $folder_mount_point_list ) counter=0 for i in disk1 disk2 disk3 disk4 disk4 disk5 disk6 do folder_name=${folderArray[counter]} mkdir /data/$folder_name let counter=$counter+1 done 现在我们要更改不带计数器的代码,并让= $ counter = counter + 1 是否有可能转移每个循环数组以获得下一个数组值? 像 ${folderArray[++]}

2
ls忽略“没有匹配项”
我想列出的所有文件的文件夹,名为中foldername有扩展test,atest或btest。 我立即想到要跑步 ls ./foldername/*.{a,b,}test 除非扩展名没有任何内容,否则此方法工作正常atest,在这种情况下,我会收到错误消息zsh: no matches found: ./foldername/*.atest。 有什么方法可以简单地忽略此错误并打印确实存在的文件? 我需要在ZSH和BASH中都可以使用。

6
基于返回值而不是退出代码构造管道的优美方法?
当状态代码无效时,是否仍然可以根据stdout的输出构造管道? 我希望答案不是解决用例,而是shell脚本范围内的问题。我要尝试做的是根据国家和语言代码猜测名称,从而找到存储库中最具体的软件包。 以这个为例 $PACKAGE1=hunspell-en-zz $PACKAGE2=hunspell-en 第一个猜测更合适,但可能不存在。在这种情况下,我想回到hunspell-en($PACKAGE2),因为第一个选项hunspell-en-zz($PACKAGE1)也不会存在。 apt-cache的管道 apt-cache只要命令能够运行(从的文档apt-cache),该命令就会返回成功(由shell定义为退出代码零) apt-cache在正常运行时返回零,在错误时返回十进制。 这使得在管道中使用该命令更加困难。通常,我期望404的等效程序包搜索会导致错误(如curl或会发生wget)。我想搜索以查看是否存在一个软件包,如果不存在,则回退到另一个软件包。 这不会返回任何内容,因为第一个命令将返回成功(因此,||从不运行rhs ) apt-cache search hunspell-en-zz || apt-cache search hunspell-en apt-cache search 有两个参数 这不会返回任何内容,因为apt-cache它的参数是AND, apt-cache search hunspell-en-zz hunspell-en 来自的文档 apt-cache 可以使用单独的参数来指定多个和在一起的搜索模式。 因此,由于其中一个参数显然不存在,因此不会返回任何内容。 问题 什么是外壳惯用语来处理约定,例如apt-cache在返回代码对任务无用的情况下?而成功仅取决于STDOUT上是否存在输出? 相似 一无所获使查找失败 他们都源于同一个问题。那里选择的答案提到find -z了可悲的是这里不适用于解决方案,并且是针对用例的。没有提及习惯用法或在不使用空终止的情况下构建管道(不是的选项apt-cache)

4
使用IFS分割字串
我已经编写了一个示例脚本来拆分字符串,但是无法正常工作 #!/bin/bash IN="One-XX-X-17.0.0" IFS='-' read -r -a ADDR <<< "$IN" for i in "${ADDR[@]}"; do echo "Element:$i" done #split 17.0.0 into NUM IFS='.' read -a array <<<${ADDR[3]}; for element in "${array[@]}" do echo "Num:$element" done 输出 One XX X 17.0.0 17 0 0 但我希望输出为: One XX X 17.0.0 17 0 …

3
从另一个数组引用bash数组变量
我想编写一个脚本来引用另一个包含这些数组变量名的数组。 到目前为止,这是我的代码: #!/bin/bash array1=('array1string1' 'array1string2') array2=('array2string1' 'array2string2') array_names=('array1' 'array2') for a in ${array_names[@]} do for b in ${a[@]} do echo $b done done 我希望输出扫描这两个数组(从外部for循环)并在内部for循环中打印相应的字符串,从而调用echo。我当前的输出只是向我显示: array1 array2 对此,我将不胜感激。谢谢!

1
在bash中创建我自己的cp函数
对于一项作业,我被要求巧妙地编写一个bash函数,该函数具有与该函数cp(副本)相同的基本功能。它仅需将一个文件复制到另一个文件,因此无需将多个文件复制到新目录。 由于我是bash语言的新手,所以我不明白为什么我的程序无法正常工作。原始功能要求覆盖文件(如果已存在),因此我尝试实现该功能。它失败。 该文件似乎在多行上失败了,但最重要的是,在这种情况下,它检查了要复制到的文件是否已经存在([-e "$2"])。即使这样,它仍然显示如果满足该条件则应该触发的消息(文件名...)。 谁能帮助我修复此文件,从而可能对我的基本语言理解有所帮助?代码如下。 #!/bin/sh echo "file variable: $2" if [-e file]&> /dev/null then echo "The file name already exists, want to overwrite? (yes/no)" read | tr "[A-Z]" "[a-z]" if [$REPLY -eq "yes"] ; then rm "$2" echo $2 > "$2" exit 0 else exit 1 fi else cat …

5
更改逗号分隔列表中的最后一个条目
我有一个巨大的文本文件,如下所示: 36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,3 36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,8 36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,14 36,53,15596,0.58454577855,0.26119,2.24878677855,0.116147072052964,12 所需的输出是这样的: 36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-03 36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-08 36,53,90478,0.58699759849,0.33616,4.83449759849,0.0695335954050315,MI-14 36,53,15596,0.58454577855,0.26119,2.24878677855,0.116147072052964,MI-12 我曾在这里和其他社区尝试过其他相关职位,但无法完全得到我想要的东西。 更新 这是交叉询问(我想要Unix / perl答案和批处理/ powershell解决方案。),它有有趣的答案。

2
从发现到grep
我想做什么? 编写一个命令,查找我项目中任何其他文件都不需要的文件。 我尝试了什么? 我find用来获取文件名列表。现在,我想使用文件名作为搜索字符串(而不是要搜索的文件)。 我find server/lib -type f -exec basename {} \; | cut -f 1 -d '.'用来获取文件名列表并剥离文件扩展名。 现在,我知道这grep -R --exclude-dir=node_modules <search-string> . -l是我想将每个文件名传递到的内容,但是我不知道如何将它们作为<search-string>参数传递。 其他资讯 我也隐约地意识到,对此的管道grep传递可能会通过find(整个文件列表)如果我要这么做的话,我显然不想这样做,然后告诉我。 另外,(尽管这可能不在此问题的范围之内),因为我将其用作查找任何grep无法为其找到任何文件名的文件名的方法,对于获得这种输出的任何建议将不胜感激 > <the-command> filename1 server/lib/foo.js # where these are the list of files in which it appears test/lib/foo.js filename2 Not Found! #where `filename2` wasn't …


2
在systemd脚本中为true时运行
我得到了一个bash脚本,基本上运行了这个脚本: #!/bin/bash [...] while true; do str="broadcast "`randArrayElement "messages[@]"` server_send_message $str sleep $interval done 现在,我要将其作为systemd服务运行,我的服务脚本如下所示: [Unit] Description=Announcer After=network.target [Service] ExecStart=/usr/local/bin/somescript &; disown ExecStop=/usr/bin/kill -9 `cat /tmp/somescript.pid` Type=forking PIDFile=/tmp/somescript.pid [Install] WantedBy=default.target 不幸的是,当我通过service somescript start它运行该服务时,但是由于while true循环,我的终端无法启动脚本: ● somescript.service - somescript service Loaded: loaded (/etc/systemd/system/somescript.service; disabled; vendor preset: enabled) Active: activating (start) since …


2
当有多个指向可执行文件的符号链接时,如何使用包装脚本记录调用
长话短说:我想跟踪一些可执行文件的调用方式,以跟踪某些系统行为。假设我有一个可执行文件: /usr/bin/do_stuff 实际上,它通过符号链接由许多不同的名称调用: /usr/bin/make_tea -> /usr/bin/do_stuff /usr/bin/make_coffee -> /usr/bin/do_stuff 等等。显然,do_stuff将使用接收到的第一个参数来确定实际要执行的操作,其余的参数将根据该参数进行处理。 我想记录一下对它的调用/usr/bin/do_stuff(以及完整的参数列表)。如果没有符号链接,我会干脆转移do_stuff到do_stuff_real写一个脚本 #!/bin/sh echo "$0 $@" >> logfile /usr/bin/do_stuff_real "$@" 但是,据我所知,它将检查调用它的名称,这将不起作用。如何编写脚本以实现相同但仍传递给do_stuff正确的“可执行使用名称”? 为了记录在案,请避免出现以下情况的答案: 我知道我可以用C语言(使用execve)来做到这一点,但是如果我可以在这种情况下只使用shell脚本,那会容易得多。 我不能简单地do_stuff用日志记录程序代替。

3
通过就地编辑进行Sed更改文件的组所有权
我有shell(php)脚本,可以通过这种方式与目标文件联系: 检查文件和目录是否可写与php的is_writable()(我不认为这是问题) 使用以下sed命令进行就地文件编辑: grep -q "$search" "$passwd_file" && { sed -i "s|$search|$replace|" "$passwd_file"; printf "Password changed!\n"; } || printf "Password not changed!\n" 因此,我得到这是(一切正确的,但)文件myuser:www-data是myuser:myuser。 是否可以sed更改文件组的所有权?如果可能,如何避免更改?

1
在awk脚本中陷阱Ctrl-C
我相信Ctrl- C可以陷入bash脚本中。是否也可以将其捕获在Awk脚本中以处理该事件? 例如,对于中止处理,而是打印已经处理过的结果,而不是仅静默退出?

1
改善我的Bash脚本
我需要改进我的Bash脚本,以使其完美运行而不会出现问题。该脚本ds4drv在其中使用,并且我不确定如何更正某些问题。 第一个问题是,在检测到控制器时它并不总是运行或正常工作,我已经为其创建了udev规则,但尚不清楚为什么在检测到该控制器时并不总是运行该脚本。 第二个问题,ds4drv只能被允许以root用户身份运行,而不能以普通用户身份运行。 第三个问题,创建PID锁定文件后,我不知道如何处理它们,因此,当PID进程不再存在时,它将在之后删除PID锁定文件。很难找到有关如何在bash脚本中使用PID文件的适当文档,因此只能有1个正在运行的实例。 这是我对ds4drv的udev规则: 50-ds4drv.rules KERNEL=="uinput", GROUP="users", MODE="0666" KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="054c", ATTRS{idProduct}=="05c4", GROUP="users", MODE="0 666" KERNEL=="hidraw*", SUBSYSTEM=="hidraw", KERNELS=="0005:054C:05C4.*", GROUP="users" MODE="0666" ACTION=="add", SUBSYSTEM="usb", ATTRS{idProduct}=="054c", RUN+="/home/user/scripts/ds4check.sh", GROUP="users" , MODE="0666" 我很确定这是udev规则的样子,权限对我来说似乎是正确的,因为它对GROUP用户是读写的。似乎确实存在一些问题的实例,一旦我的bash脚本运行并且此规则设置为在连接控制器设备时自动运行,那么某些游戏将变得无响应,例如在没有控制器设备的情况下就连接了它。采取行动,/dev/js0而是采取行动/dev/js1。特别是如果它不是以root身份执行的,通常会返回此错误。 OSError: [Errno 13] Permission denied: '/dev/input/event17' 当然还有bash脚本; ds4check.sh #!/bin/bash # DS4 Check Script pidfile=/tmp/ds4drv.pid # check if process is already running …

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.