标签: bash-scripting

编写可在任何 shell 上运行的 shell 脚本(使用多个 shebang 行?)

我刚刚开始更深入地研究 shell 脚本,我总是把我的脚本放在一个文件中,标记它chmod +x然后完成/path/to/script.sh并让任何默认的解释器使用它,我认为它是 zsh,因为这就是我用于我的外壳。显然,它似乎只是/bin/sh默认情况下,即使我从 zsh 提示符执行脚本,因为我开始将特定于 zsh 的东西放入我的脚本中,除非我运行zsh /path/to/script.sh.

为了切入正题,以下是我的问题:

  1. 当#!/path/to/shell开头没有 shebang 行 ( )时,哪个 shell 执行脚本?我假设/bin/sh但我无法确认。
  2. 在编写可在任何平台上运行的 shell 脚本方面,什么被认为是“最佳实践”?(好吧,这是一种开放式)
  3. 如果 zsh 不可用,是否可以编写一个尝试使用 zsh 并回退到 bash 的脚本?我试过放置两条shebang行,如下所示,但是bad interpreter: /bin/zsh: no such file or directory如果我在没有zsh的机器上尝试它只会出错。

    #!/bin/zsh

    #!/bin/bash

bash zsh shell shell-script bash-scripting

21
推荐指数
1
解决办法
7820
查看次数

在bash中的变量中用正斜杠(“/”)替换反斜杠(“\”)

我想用bash 中的变量中的\正斜杠(/)替换反斜杠()。我这样试过,但它不起作用:

home_mf = ${home//(\)//(/)}
Run Code Online (Sandbox Code Playgroud)

例如,我想

\a\b\c -> /a/b/c
Run Code Online (Sandbox Code Playgroud)

bash bash-scripting

20
推荐指数
2
解决办法
4万
查看次数

如何在 bash 脚本中切换/更改用户 ID 以在同一脚本中执行命令?

有没有办法在脚本中切换用户身份(作为安装过程的一部分以 root 身份执行)以执行某些命令而不调用外部脚本,然后返回root运行其他命令?

有点:

#!/bin/bash
some commands as root
SWITCH_USER_TO user
some commands as user including environment variables checks, without calling an external script
SWITCH_USER_BACK
some other stuff as root, maybe another user id change...
Run Code Online (Sandbox Code Playgroud)

sudo bash bash-scripting

17
推荐指数
1
解决办法
2万
查看次数

使用 shell 脚本/命令编辑 xml 文件

我需要使用 unix 脚本或命令执行此操作 /home/user/app/xmlfiles 中有一个 xml 文件,例如

<book>
   <fiction type='a'>
      <author type=''></author>
   </fiction>
   <fiction type='b'>
      <author type=''></author>
   </fiction>
   <Romance>
       <author type=''></author>
   </Romance>
</book>
Run Code Online (Sandbox Code Playgroud)

我想将小说中的作者类型编辑为 local 。

   <fiction>
      <author type='Local'></author>
   </fiction>
Run Code Online (Sandbox Code Playgroud)

我需要单独使用属性 b更改小说标签中的作者类型。请使用 unix shell 脚本或命令帮助我解决这个问题。谢谢 !

unix bash shell shell-script bash-scripting

17
推荐指数
3
解决办法
7万
查看次数

运行时命令每个输出的前缀

我正在尝试制作一个模块化脚本。我有几个从单个脚本调用的脚本/命令。
我想为每个单独命令的输出添加前缀。

例子:

我的文件都是commands.sh/command1.sh/command2.sh

command1.sh输出
file exists
file moved

command2.sh输出
file copied
file emptied

allcommands.sh运行脚本command1.sh和command2.sh

我想为这两个脚本的每个输出添加前缀,如下所示:
[command1] file exists
[command1] file moved
[command2] file copied
[command2] file emptied

linux bash shell command-line bash-scripting

16
推荐指数
2
解决办法
1万
查看次数

将时间戳附加到 tail -f 结果

我想在从“tail -f 输出文件”出来的每一行前面打印一个时间戳,这样我就知道每行什么时候打印出来。像:

[...]
20110617_070222:这里打印的结果
20110617_070312:这里打印的结果
20110617_070412:这里打印的结果
20110617_070513:结果打印在这里
[...]

有任何想法吗?

tail bash-scripting

15
推荐指数
2
解决办法
7956
查看次数

如何按行截断文件?

我有大量文件,其中一些文件很长。如果它们更大,我想通过删除文件的末尾将它们截断到一定的大小。但我只想删除整行。我怎样才能做到这一点?感觉就像 Linux 工具链可以处理的那种事情,但我不知道正确的命令。

例如,假设我有一个包含 300 字节行的 120,000 字节文件,我试图将其截断为 10,000 字节。前 33 行应该保留(9900 字节),其余的应该被删除。我不想精确地削减 10,000 个字节,因为那会留下部分行。

当然,文件的长度不同,行的长度也不一样。

理想情况下,生成的文件会稍微短一些,而不是稍微长一些(如果断点在一条长线上),但这不是太重要,如果这样更容易的话,它可能会更长一点。我希望直接对文件进行更改(好吧,可能是新文件复制到别处,原始文件已删除,新文件已移动,但这与用户的 POV 相同)。将数据重定向到一堆地方然后返回的解决方案可能会损坏文件,我想避免这种情况......

linux bash-scripting

15
推荐指数
2
解决办法
2万
查看次数

正确转义 bash 脚本中的正斜杠以与 sed 一起使用

我试图通过在干模式下运行 rsync 来确定在同步两个文件夹时新复制的文件的大小,然后总结 rsync 输出中列出的文件的大小。

目前我被困在文件的父文件夹前缀上。我发现了如何使用 sed 为行添加前缀以及如何使用 sed 进行转义,但是我在将这两者结合起来时遇到了麻烦。

这是我走了多远:

source="/my/source/folder/"
target="/my/target/folder/"
escaped=`echo "$source" | sed -e 's/[\/&]/\\//g'`
du `rsync -ahnv $source $target | tail -n +2 | head -n -3 | sed "s/^/$escaped/"` | awk '{i+=$1} END {print i}'
Run Code Online (Sandbox Code Playgroud)

这是我从 bash -x myscript.sh 得到的输出

+ source=/my/source/folder/
+ target=/my/target/folder
++ echo /my/source/folder/
++ sed -e 's/[\/&]/\//g'
+ escaped=/my/source/folder/
+ awk '{i+=$1} END {print i}'
++ rsync -ahnv /my/source/folder/ /my/target/folder/
++ sed 's/^//my/source/folder//'
++ head -n -3
++ tail -n …
Run Code Online (Sandbox Code Playgroud)

linux bash rsync sed bash-scripting

15
推荐指数
1
解决办法
2万
查看次数

如何获取链接目标的完整路径

如果我有一个/var/opt/foo用ln -fs /path/to/target/dir foo. 如何在只看到链接的脚本中获取/path/to/target/dir?

我想在脚本中实现的是rm -rf /path/to/target/dir在我做之前ln -fs /path/to/another/dir foo。

bash symbolic-link bash-scripting

13
推荐指数
1
解决办法
1万
查看次数

awk / sed 只打印到下划线字符

如何使用 awk 或 sed 将字符串打印到第一个下划线字符?

前:

host100_044 2
host101_045 2
host102_046 2
Run Code Online (Sandbox Code Playgroud)

后:

host100
host101
host102
Run Code Online (Sandbox Code Playgroud)

unix unix-utils bash-scripting

13
推荐指数
1
解决办法
5万
查看次数