linux - 协助复制文件的 bash 脚本

标签 linux bash shell copy

我是 linux 的新手,也是 bash 编程/脚本的新手。 总之,我想制作一个 bash 脚本来做一些事情:

  1. 将获得有关要复制哪些文件的输入
  2. 会得到dest文件夹
  3. 会询问是复制还是移动
  4. 将执行所需的操作
  5. 最后会询问是否继续进行其他操作

现在,至于第 2、3、5 部分我没问题,但第 1 部分有点问题。 所以,这是脚本,我希望你能告诉我我哪里错了以及为什么 :)

#! /bin/bash
#beginning
clear
f=1

Beginning()
{
    echo "HELLO $USER , THIS PROGRAM WILL COPY THE FILES YOU WANT TO YOUR DESIRED DESTINATION DIRECTORY"
    echo -n "please enter the filname/s you want to copy (up to 6 files at a time): ";
    echo
    EnteringF
}

EnteringF()
{
    echo " filename$f : ";
    read cop$f
    Confirm
}

Confirm()
{
    echo "do you wish to copy another file (y/n)?";
    read ans
    if [ "$ans" = "y" ] || [ "$ans" = "Y" ]; then
        f=$[sum=$f+1]
        EnteringF
    elif [ "$ans" = "n" ] || [ "$ans" = "N" ]; then
        Destination
    else
        echo " invalid choice please try again "
        Confirm
    fi
}

Destination()
{
    echo -n "now please enter the destination folder:";
    read dest;
    CopyMove
}
CopyMove() 
{ 
    echo -n "Do you want to copy or move the files/s? please enter c/m? "; 
    read choice; 
    if [ "$choice" = "c" ] || [ "$choice" = "C" ]; then 
        cp "$cop$f" "$dest"; 
        echo "copied successfully" 
        UseAgain 
    elif [ "$choice" = "m" ] || [ "$choice" = "M" ] ; then 
        mv [ "$files" + "$f" ] "$dest"
        echo "moved successfully" 
        UseAgain 
    else 
        echo " invalid choice please try again "; 
        CopyMove 
    fi
}
UseAgain()
{
    echo "Do you want to use the program again y/n?";
    read confirm
    if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
        Beginning
        UseAgain
    elif [ "$confirm" = "n" ] || [ "$confirm" = "N" ]; then
        End
    else
        echo "invalid choice please try again"; UseAgain
    fi
}
End()
{
    clear
    echo "THANK YOU $USER FOR USING THIS PROGRAM :-)" 
}

Beginning

现在我的主要问题是没有数据被记录到 cop 变量,因此 cp 没有什么可以复制的。 也许我应该使用其他循环,但我仍然不知道如何使用其他循环。

最佳答案

您想使用数组。我已经重写了您的部分代码:

#!/bin/bash

clear
f=0
cop=()

abort() {
    echo >&2 "Something went wrong ($@)."
    echo >&2 "Do you have a banana jammed in the keyboard?"
    exit 1
}

Beginning() {
    echo "HELLO $USER , THIS PROGRAM WILL COPY THE FILES YOU WANT TO YOUR DESIRED DESTINATION DIRECTORY"
    echo "please enter the filename/s you want to copy:"
    EnteringF
}

EnteringF() {
    local i=$((${#cop[@]}+1))
    IFS= read -r -e -p " filename$i: " f || abort "EnteringF"
    cop+=( "$f" )
    Confirm
}

Confirm() {
    local ans
    read -e -p "do you wish to copy another file (y/n)? " ans || abort "Confirm"
    if [[ "${ans,,}" = y ]]; then
        EnteringF
    elif [[ "${ans,,}" = "n" ]]; then
        Destination
    else
        echo " invalid choice please try again "
        Confirm
    fi
}

Destination() {
    IFS= read -r -e -p "now please enter the destination folder: " dest || abort "Destination"
    CopyMove
}

CopyMove() { 
    read -r -e -p "Do you want to copy or move the file/s? please enter c/m? " choice || abort "CopyMove"
    if [[ "${choice,,}" = c ]]; then 
        if cp -v -- "${cop[@]}" "$dest"; then
            echo "copied successfully"
        else
            abort "cp"
        fi
        UseAgain 
    elif [[ "${choice,,}" = m ]] ; then 
        if mv -v -- "${cop[@]}" "$dest"; then
            echo "moved successfully"
        else
            abort "mv"
        fi
        UseAgain 
    else 
        echo " invalid choice please try again "
        CopyMove 
    fi
}

UseAgain() {
    read -e "Do you want to use the program again y/n? " confirm || abort "UseAgain"
    if [[ "${confirm,,}" = y ]]; then
        Beginning
        UseAgain
    elif [[ "${confirm,,}" = "n" ]]; then
        End
    else
        echo "invalid choice please try again";
        UseAgain
    fi
}
End() {
    clear
    echo "THANK YOU $USER FOR USING THIS PROGRAM :-)" 
}

Beginning

我什至不确定它是否有效,当我尝试运行它时出现了黑屏和可怕的提示,询问我要复制或移动什么文件。我期待一匹小马或像猫弹钢琴一样非常酷的东西。但不是。实际上,我不知道我想移动什么文件。我什至不确定我是否想移动文件。如果我想移动文件,我会直接使用 mv。我已经使用了一些 bashisms 供您挖掘。

关于cop这个变量的问题,我用的是数组,所有的问题一下子就没有了!

更重要的是,您的程序中存在巨大的设计缺陷:递归!它是可怕的。你在每一步都在堆叠,从不释放堆叠。你真的应该重新考虑你的设计!看:如果你调用你的程序 lol_pony_cat,如果你在终端中输入:

yes '42' | ./lol_pony_cat

你很快就会得到

Segmentation fault

那是因为:

  • 我们从头开始
  • 我们进入 EnteringF 并提示输入文件名:我们输入 42
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了一个无效的 42,所以
  • 我们进入 Confirm 并提示输入 y/n,但我们回答了无效的 42,所以...

像这样直到我们到达堆栈溢出。

祝你好运。

关于linux - 协助复制文件的 bash 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19747543/

相关文章:

c - system() 调用在 C 中返回错误值

linux - 如何使用scp同时复制多个文件

c++ - 输入/输出管道

python - Bash 隐形打字

linux - 如何从 svn 状态循环 linux 中的文件

linux - 从 SSH-Shell 启动 Gnome-Application

linux - 具有 Oracle Linux 7 基础镜像的 Mesos 从属容器无法启动

linux - Bash中的 'eval'命令及其典型用途

linux - bash |管道到 bash 函数

linux - 如何将我的输入 token 传递给 zsh 别名中的嵌套命令