Question

Je reçois les messages suivants souvent, par exemple, lorsque les fichiers d'adaptation dev à une branche maître

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

Je voudrais être interrogé sur la création des dossiers donnés tels que ma commande initiale sera exécutée si je réponds oui à la question (s).

Ma tentative de pseudo-code quand je suis en train de copier un fichier dans un répertoire qui n'existe pas

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

Problèmes

  1. Pour modifier le message d'avertissement: Quel fichier ne contrôle le "Aucun fichier ou répertoire" -command
  2. Pour gratter le chemin dans la commande initiale et mkidr chemin sans le fichier : Comment se gratter le chemin dans la commande initiale
  3. Pour gratter de la fin avec votre langue choisie, comme AWK: Comment supprimer le dernier match dans le chemin quand / est le séparateur de champ? Je ne sais pas comment vous pouvez gratter les lettres à partir de la fin avec AWK.
Était-ce utile?

La solution

Voici une fonction que j'ai écrit qui travaillera en zsh, bash ou ksh.

Remarque: Il a le débogage activé (il fait écho aux commandes qu'il courrait plutôt que de les exécuter). Si vous commentez cette ligne, il sera en fait de les exécuter.

Attention . Il n'a pas été complètement testé

Pour l'utiliser, placez ce script dans un fichier appelé cpmd dans /usr/local/bin (ou ailleurs dans votre chemin). Pour l'activer, à partir de l'invite du shell tapez la commande suivante (ou l'ajouter à votre script de démarrage - pour bash il serait ~/.bashrc):

source cpmd

Ensuite, vous pouvez copier un fichier en utilisant une commande comme ceci:

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

Ni répertoire « inexistant » ou « newdir » existent encore. Les deux répertoires sont créés le fichier nommé « carparts » est copié « newdir ».

Si vous ne pas inclure une barre oblique ( « / ») à la fin, la dernière partie est traitée comme un nom de fichier et les répertoires inexistants avant qui sont créés:

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

Le répertoire « anothernew » est créé alors « fournitures » est copié avec le nouveau nom de fichier « consommables ».

Si tous les répertoires dans la destination existent déjà, cpmd agit comme la commande cp régulière.

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
}

Autres conseils

Ce message d'erreur provient de la commande cp, pas zsh. Si vous voulez améliorer la sortie, vous allez devoir écrire la logique pour tronquer et examiner le chemin le long de la vérification pour voir si elle existe ou non.

Il existe des commandes pour aider à cela, un coup d'oeil à basename (1) et dirname (1).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top