Domanda

Ottengo i seguenti messaggi, spesso, ad esempio quando copia i file dev ad un ramo maestro

cp: /Users/Masi/gitHub/shells/zsh/dvorak: No such file or directory
cp: /Users/Masi/gitHub/shells/zsh/dvorak2: No such file or directory

Vorrei essere chiesto circa la creazione delle cartelle indicate in modo tale che il mio comando iniziale sarà eseguito se rispondo di sì alla domanda (s).

Il mio tentativo in pseudo-codice quando sto cercando di copiare un file in una directory che non esiste

if no such a directory exists, then asks users about to create it:
   if yes, then mkdir directory AND run the initial command again
   else do noting

Problemi

  1. Per modificare il messaggio di avviso:? Quale file non controllare il "No such file or directory" -command
  2. Per raschiare il percorso nel comando AND mkidr percorso iniziale senza il file :? Come avrebbe raschiare il percorso nel comando iniziale
  3. Per raschiare dalla fine con la lingua scelta come AWK: Come si rimuovere l'ultima partita nel percorso quando / è il separatore di campo? io non sono sicuro di come si può raschiare le lettere a partire dalla fine con AWK.
È stato utile?

Soluzione

Ecco una funzione che ho scritto, che funzionerà in zsh, bash o ksh.

Nota: E 'il debugging abilitato (si fa eco i comandi sarebbe correre piuttosto che la loro esecuzione). Se si commenta che la linea, sarà effettivamente eseguirli.

Attenzione :. non è stato accuratamente testato

Per usarlo, mettere questo script in un file chiamato cpmd in /usr/local/bin (o altrove nel vostro percorso). Per attivarlo, dal prompt della shell digitate il seguente comando (o aggiungere al vostro script di avvio - per bash sarebbe ~/.bashrc):

source cpmd

Quindi è possibile copiare un file utilizzando un comando come questo:

cpmd carparts /home/dave/Documents/nonexistent/newdir/

Né directory "inesistente" o "newdir" esiste ancora. Entrambe le directory sono create quindi il file denominato "carparts" vengono copiati "newdir".

Se non si include una barra ( "/") alla fine, l'ultima parte viene trattato come un nome di file e le directory inesistenti prima che si creano:

cpmd supplies /home/dave/Documents/anothernew/consumables

La directory "anothernew" viene creato quindi "forniture" viene copiato con il nuovo nome "di consumo".

Se esistono già tutte le directory nella destinazione, cpmd si comporta come il comando normale cp.

function cpmd {
    # copies files and makes intermediate dest. directories if they don't exist
    # for bash, ksh or zsh
    # by Dennis Williamson - 2009-06-14
    # http://stackoverflow.com/questions/993266/unable-to-make-nosuchdirectory-message-useful-in-zsh

    # WARNING: no validation is performed on $1 and $2

    # all cp commands below are hardcoded with -i (interactive) to prevent overwriting

   if [[ -n $KSH_VERSION ]]
   then
       alias local=typeset
       local func="$0"
       local lastchar="${2: -1}"
       readcmd () { read "$2?$1"; }
    elif [[ -n $ZSH_VERSION ]]
    then
        local func="$0"
        # the following two lines are split up instead of doing "${2[-1]}"
        # to keep ksh from complaining when the function is loaded
        local dest="$2"
        local lastchar="${dest[-1]}"
        readcmd () { read "$2?$1"; }
    elif [[ -n $BASH_VERSION ]]
    then
    local func="$FUNCNAME"
        local lastchar="${2:(-1)}"
        readcmd () { read -p "$1" $2; }
    else
        echo "cpmd has only been tested in bash, ksh and zsh." >&2
        return 1
    fi

    local DEBUG='echo' # COMMENT THIS OUT to make this function actually work

    if [[ ${#@} != 2 ]]
    then
        echo "$func: invalid number of parameters
Usage:
  $func source destination

  where 'destination' can include nonexistent directories (which will
  be created). You must end 'destination' with a / in order for it to
  specify only directories. Without the final slash, the 'source' will
  be copied with a new name (the last portion of 'destination'). If you
  are copying multiple files and 'destination' is not a directory, the
  copy will fail." >&2
        return 1
    fi

    local dir=$(dirname "$2")
    local response
    local nl=$'\n'

    # destination ($2) is presumed to be in one of the following formats:
    # .../existdir              test 1  (-d "$2")
    # .../existdir/existfile    test 2  (-f "$2")
    # .../existdir/newfile      test 3  (-d "$dir" && $lastchar != '/')
    # .../existdir/newdir/      (else)
    # .../newdir/newdir/        (else)
    # .../newdir/newfile        (else)

    if [[ -d "$2" || -f "$2" || (-d "$dir" && $lastchar != '/') ]]
    then
        $DEBUG cp -i "$1" "$2"
    else
        if [[ $lastchar == '/' ]]
        then
            dir="$2"
        fi
        local prompt="$func: The destination directory...${nl}  ${dir}${nl}...does not exist. Create? (y/n): "
        while [[ -z $response ]]
        do
            readcmd "$prompt" response
            case $response in
                y|Y) response="Y" ;;
                n|N) ;;
                *) response=
                   prompt="$func: Invalid response.${nl}  Create destination directory? (y/n): ";;
            esac
        done
        if [[ $response == "Y" ]]
        then
            $DEBUG mkdir -p "$dir" && $DEBUG cp -i "$1" "$2"
        else
            echo "$func: Cancelled." >&2
        fi
    fi
}

Altri suggerimenti

Questo messaggio di errore è venuta dal comando cp, non zsh. Se si vuole migliorare l'output, si sta andando ad avere per scrivere la logica per troncare ed esaminando il percorso lungo con il controllo per vedere se esiste o meno.

Non ci sono i comandi per assistere con questo, hanno uno sguardo al nome base (1) e dirname (1).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top