8
votes

Emacs Workflow pour éditer des scripts Bash pendant qu'ils courent

bash peut donner résultats inattendus si on édite un script pendant que le script est en cours d'exécution . Mais il serait souvent très pratique de pouvoir éditer une copie temporaire d'un script que je rencontre dans une coquille, mais assurez-vous qu'il est de retour dans l'emplacement d'origine avant que je ne puisse la reculer. Quelqu'un a-t-il des suggestions pour un flux de travail ou des personnalisations vers EMACS pour faciliter cela?


0 commentaires

4 Réponses :


2
votes

J'ai déjà eu une fonction pour renommer le fichier de mémoire tampon actuel. Était un coup court à une fonction qui a facilité une version temporelle à une version temporaire d'un fichier, puis de retour. Fondamentalement, si vous exécutez cette fonction lors de la visite d'un fichier normal "foo.txt", il copiera le fichier sur un nouveau fichier dans le même Dir avec le nom "tmp.foo.txt". éditer comme souhaité. Lorsque vous êtes prêt à passer à nouveau, exécutez la fonction et il déplacera le fichier temporel sur le fichier d'origine. J'ai utilisé le préfixe "TMP". Au lieu d'un suffixe, car la reconnaissance de la plupart des modes dans EMACS est basée sur le suffixe (vous pouvez probablement faire quelque chose de favorable à vous souvenir de tous les modes tampons et à réappliquer ...).

(defun toggle-temp-file ()
  (interactive)
  (let* ((cur-buf (current-buffer))
         (cur-file (buffer-file-name cur-buf))
         (cur-file-dir (file-name-directory cur-file))
         (cur-file-name (file-name-nondirectory cur-file))
         new-file)
    (if (string-match "^tmp\\.\\(.+\\)\\'" cur-file-name)
        ;; temp file -> orig file
        (progn
          (setq new-file
                (concat cur-file-dir (match-string 1 cur-file-name)))
          (rename-file cur-file new-file t))
      ;; orig file -> temp file
      (setq new-file (concat cur-file-dir "tmp." cur-file-name))
      (copy-file cur-file new-file nil nil t))
    (kill-buffer cur-buf)
    (find-file new-file)))


0 commentaires

7
votes

mx Supprimer-fichier , appuyez sur down pour insérer obtenir le chemin d'accès au fichier que vous modifiez et ret pour supprimer le fichier . Lorsque vous enregistrez votre mémoire tampon, cela créera un nouveau fichier. Bash continuera à exécuter l'ancien fichier, supprimé.

Au fait, dans la plupart des cas, vous n'avez même pas besoin de prendre cette précaution. Emacs enregistre généralement dans un fichier temporaire, puis renomme que le fichier temporaire au nom de fichier approprié (qui supprime l'ancien fichier, sauf s'il est conservé comme sauvegarde). Emacs ne écrase que le fichier en place s'il détecte qu'il ne peut pas recréer le fichier correctement: si le fichier a des liens difficiles, ou si vous n'avez pas l'autorisation d'écriture sur le répertoire. (Je simplifie un peu; les détails sont dans la fonction Basic-Save-Buffer-2 Dans Files.el .) Tant que le fichier a un répertoire unique Entrée et vous avez des autorisations d'écriture sur le répertoire contenant le script, appuyez simplement sur CX CS .


5 commentaires

Cela semble vraiment simple. J'ai besoin de vérifier que cela fonctionne réellement. Si tel est le cas, cela signifie-t-il que le comportement de sauvegarde existant-and-renommé d'Emacs gardera ce problème de la culture?


@Michaelhoffman Oui, si EMACS effectue Save-and-Rename (qui est le comportement par défaut dans la plupart des cas), vous n'aurez pas du tout ce problème. Notez que je suppose un vrai Unix ici, si vous exécutez bash sur quelque chose comme Cygwin, vous ne pourrez peut-être pas supprimer le fichier (je ne suis pas sûr de cela).


Pouvez-vous s'il vous plaît éditer votre réponse pour inclure ceci? Il semble que toute la question était inutile, car Emacs fait la bonne chose de la boîte.


Si la description du comportement par défaut de l'EMACS était vraie en 2011, il semble que cela ait changé pour le pire (au moins jusqu'à cette question, à moins d'avoir manqué quelque chose, ce qui est certainement possible). Fichier-précieux-drapeau est nil par défaut (mais peut casser des liens rigides si activé). Le nombre numéro de liens matériels n'est considéré que si break-hardlink-on-sauvegarde est non- nil (lequel il n'est pas par défaut ). Je ne vois aucune configuration qui signifierait "ne cassera jamais des liens rigides, mais sinon écriture-temp-dig-file-and-renommé si possible" ...


... cela peut être partiellement atténué par le paramètre sauvegarde par défaut par défaut ( nil ), car EMACS renommerait le fichier d'origine à Soyez une sauvegarde, puis créez un nouveau fichier pour le nom de fichier d'origine; Cependant, cela ne s'appliquerait que si une sauvegarde s'est effectivement survenue.



7
votes

[EDIT] The Meilleure solution de contournement est effectué en écriture Shell, pas dans emacs. En bref, _put tout dans une attelle et mettez "sortie" avant la suppression de fermeture. Lire la réponse liée bien pour éviter les pièges.

Dans cette réponse, je complète la réponse de Gilles avec la théorie.

La suppression de la raison est sûre mais la modification n'est pas la modification à UNIX, un fichier supprimé est inaccessible à partir du système de fichiers, mais les processus qui avaient ouvert le fichier (ici, / bin / bash) peuvent toujours le lire, comme expliqué ici . Ce n'est pas que Bash fait quelque chose de spécial, comme la mise sous forme de tamponner tout le dossier, mais il lit simplement. (Même après la suppression, vous pouvez récupérer le script lorsqu'il est en cours d'exécution, comme expliqué ici . En bash, le script semble toujours être ouvert comme 255, / proc / / fd / 255 .)

[modifier] Mon Ancienne réponse incluse EMACS Solution et CO, conformément à la demande de PO. Mais après des années d'expérience , je suis sûr que le pointeur ci-dessus est le meilleur, beaucoup mieux que toute autre tentative.)


0 commentaires

2
votes

Il suffit d'ajouter cette solution à titre de moyen simple et propre de protéger les scripts Bash en cours de modification:

#! /bin/bash
{
your_code;
exit;
}


1 commentaires

Mentionné à la fin de la réponse de Teika Kazura aussi, mais toujours utile de la mettre en valeur, je pense.