协助bash脚本复制文件

时间:2013-11-02 22:21:05

标签: linux bash shell copy

我是linux的新手,也是打击编程/脚本的人。 无论如何,我想制作一个bash脚本来完成一些事情:

  1. 将获得有关要复制的文件的输入
  2. 将获取dest文件夹
  3. 会要求他们复制或移动
  4. 将执行所需的操作
  5. 将在最后询问是否继续采取其他行动
  6. 现在,至于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无需复制。 也许我应该使用其他一些循环,但我仍然不知道如何使用其他循环。

1 个答案:

答案 0 :(得分:3)

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

#!/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。我已经用了一些基本的东西来挖掘。

关于变量cop的问题,我使用了一个数组,所以所有问题都立即消失了!

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

yes '42' | ./lol_pony_cat

你很快就会获得

Segmentation fault

那是因为:

  • 我们从Beginning开始
  • 我们进入EnteringF,我们提示输入文件名:我们输入42
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示y / n,但我们会回答无效的42,所以
  • 我们进入确认状态,我们会提示您是否同意,但我们会回答无效的42,所以......

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

祝你好运。