bash程序将所有文件从一个位置复制到另一个位置

时间:2016-06-27 15:01:47

标签: bash file terminal

我正在尝试编写一个简单的bash程序,在我的终端上执行,将一个目录中的所有文件复制到另一个目录中。这是我的第一个bash程序。这就是我现在所拥有的:

<!DOCTYPE html>
<html>

<head>
  <title>Jamku Stats</title>

  <script>
    (function(i, s, o, g, r, a, m) {
      i['GoogleAnalyticsObject'] = r;
      i[r] = i[r] || function() {
        (i[r].q = i[r].q || []).push(arguments)
      }, i[r].l = 1 * new Date();
      a = s.createElement(o),
        m = s.getElementsByTagName(o)[0];
      a.async = 1;
      a.src = g;
      m.parentNode.insertBefore(a, m)
    })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', 'ga');

    ga('create', 'UA-30294621-11', 'auto');
    ga('send', 'pageview');
  </script>

</head>

<body>

  <p>Server is up and running</p>

</body>

</html>

当我在终端中运行脚本时:

#!/bin/bash
cd /Users/georgi/Loopback_projects/ESPC/common/models
for f in *.json
do
cp -v $f /Users/georgi/AndroidStudioProjects/ESPC_Retrofit/app/src/main/assets
done

它说Chriss-iMac:georgi$ exportToAndroid.sh

1 个答案:

答案 0 :(得分:2)

简短回答:

  1. 使用以下命令使脚本可执行:

    chmod +x exportToAndroid.sh
    
  2. 运行:

    ./exportToAndroid.sh
    
  3. 答案很长:

    当你在终端中输入东西时,字符串被解析,切成单词,并且(除了重定向或环境变量或其他关键字)第一个单词被理解为要执行的命令。如果shell将这个单词识别为函数或内置函数(我在这里忽略了别名),那么它运行此函数或使用给定的参数内置;但我们不是这种情况:exportToAndroid.sh不是。在这种情况下(因为这个单词不包含斜杠),shell会查看你的PATH变量以检查它是否找到一个名为exportToAndroid.sh的文件(如果找到它,它会愉快地执行它);但在这里找不到! (检查PATH变量包含echo "$PATH"的内容。)

    如果不是给出一个带有斜杠的字,而是给出一个带斜杠的路径,那么shell不会查看PATH变量,而是会尝试直接执行给定的文件。这就是为什么

    ./exportToAndroid.sh
    

    会奏效。

    如果你不想每次都在前面输入./,这是一件好事:

    1. 在您的主文件夹中使用

      创建bin/目录
      mkdir ~/bin
      
    2. 将此目录添加到PATH变量中,如下所示:在.bashrc文件末尾添加行PATH=~/bin:$PATH(嗯,这不是一种强大的前置{{} 1}}到你的~/bin变量,但它应该没问题,
    3. 将您的脚本移至PATH文件夹
    4. 重启您的Bash会话;您可以检查~/bin文件夹是否显示在~/bin变量的第一个位置{/ 1}},
    5. 几个月后,你会发现你的PATH文件夹包含了许多你完全忘记的无用的东西!
    6. 关于这一点的好处是你可以在任何目录中用echo "$PATH"调用你的脚本!

      关于您的代码的评论:

      • 在脚本中,在bin/之后,您应始终检查exportToAndroid.sh是否成功!一种可能性:

        cd
      • 当使用变量扩展时,除非你真的想要进行单词拆分和文件扩展(并且你很少想要它!实际上,这是非常罕见的练习,当我们希望这种情况发生时,我们总是写一个用来解释我们意图的评论行,你必须引用扩展名:你的cd行更好地写成

        cd /Users/georgi/Loopback_projects/ESPC/common/models || { echo "Can't cd"; exit 1; }
        

        (参见引号?)。

      • 使用glob时,如同cp一样,您应确保已启用cp -v "$f" /Users/georgi/AndroidStudioProjects/ESPC_Retrofit/app/src/main/assets (或for f in *.json)。

      此时,您的脚本应如下所示:

      shopt -s nullglob

      但实际上,更简单,更有效的方法就是这样做:

      shopt -s failglob

      效率更高,因为我们只调用#!/bin/bash shopt -s nullglob cd /Users/georgi/Loopback_projects/ESPC/common/models || { echo "Can't cd"; exit 1; } for f in *.json; do cp -v "$f" /Users/georgi/AndroidStudioProjects/ESPC_Retrofit/app/src/main/assets done 一次,而不是每个要复制的文件一次

      然而,如果要复制的文件太多,这将会失败......但它可以使用合理大小的目录。