Eğer eski UNIX kitaplarının ve e-posta listelerinin arşivlerine girdiyseniz, şüphesiz ki UNIX efsanesine rastlamışsınızdır. ed
. ed
(/iː diː/ olarak telaffuz edilir) tıpkı bir metin editörüdür vim
Ve emacs
. Ancak benzerlerinin aksine, ed
En iyi şekilde özetlenebilecek bir arayüzle birlikte gelir…
$ ed
q
?
q
?
q
?
qqqqqqqqqqqqqqqqqq
?
q
?
q
?
q
$
Tüm bunlara rağmen efsaneye göre: “ed standart metin editörüdür”. Öyle ki çoğu Linux dağıtımı /bin/ed
bir Priority
ile ilgili -100
.
$ sudo update-alternatives --config editor
There are 5 choices for the alternative editor (providing ∕usr∕bin∕editor).
Selection Path Priority Status
------------------------------------------------------------
* 0 ∕usr∕bin∕vim.gtk3 50 auto mode
1 ∕bin∕ed -100 manual mode
2 ∕bin∕nano 40 manual mode
3 ∕usr∕bin∕code 0 manual mode
4 ∕usr∕bin∕vim.gtk3 50 manual mode
5 ∕usr∕bin∕vim.tiny 15 manual mode
Şaka bir yana, sık sık olmasına rağmen micro
ve Visual Studio Code kullanıcısıyım, kendimi oyun oynarken buluyorum ed
ve bazen kaynak kodu. En önemlisi GNU uygulaması ed
.
Bu bir hikaye böcek GNU’daki özellik ed
Geçen yıl kaynak kodunu incelerken birinin işini kaybetmesine neden olabilecek bir şeye rastladım.
Zamanın kısa bir tarihi
Bu tasarım kusurunun önemini anlamak için kısaca GNU’nun kökenine geri dönmeliyiz. ed
editör. 1976’da Brian Kernighan ve PJ Plauger “Pascal’daki Yazılım Araçları” Pascal programlama dilini kullanarak iyi kod yazmayı araştıran bir kitap. Bu kitap aşağıdakiler gibi muhteşem pasajlar içeriyor:
“Bu arada, gerçek hayatta rutinin adını mutlaka koyarsınız
sort
Olumsuzbubble
böylece kullanıcıları rahatsız etmeden algoritmayı değiştirebilirsiniz.”— Brian Kernighan ve PJ Plauger, Pascal’daki Yazılım Araçları “Kabarcık Sıralaması”na referansla
Bu kitap neden bu kadar önemli? GNU’da belirtildiği gibi info
sayfa açık ed
GNU uygulaması ed
Bölüm 6’dan ilham aldı, “Düzenleme”. İlk GNU uygulaması Kernighan ve Plauger’in spesifikasyonuna göre tasarlandı.
ed-0.1 ❯ cat THANKS
[...]
GNU ed originated with the editor algorithm from Brian W. Kernighan & P.
J. Plauger's wonderful book "Software Tools in Pascal," Addison-Wesley,
1981. [...]
Kitabı okurken özellikle şu paragraf dikkatimi çekti (vurgu bana ait):
“Hata düzeltme, editörün tasarımı üzerindeki ikinci büyük etkidir. […]
edit
değerli dosyaları korur, bu nedenle dikkatli olmalıdır. […] Sorunsuz bir şekilde iyileşmesi gerekir, aksi halde küçük bir hata değerli bilgilerin kaybına neden olabilir.”— Brian Kernighan ve PJ Plauger, Pascal’da Yazılım Araçları
Bu alıntıyı aklınızda tutun. Bu pasaja birazdan geri döneceğiz.
Doğrudan kaynağa
GNU’nun nasıl olduğunu incelemek için ed
özelliğin altında çalışıyor, en son GNU sürümünün bir kopyasını alın (sürüm 1.18
Bu blog yazısını yazarken). Kaynak kodunda yalnızca 8 C dosyasıyla gezinmek kolaydır.
❯ find . -name "*.c"
./buffer.c
./io.c
./carg_parser.c
./main_loop.c
./main.c
./signal.c
./global.c
./regex.c
GNU ed
bir SIGHUP işleyicisi var signal.c
her seferinde bir yedekleme dosyası oluşturur. ed
süreç bir SIGHUP sinyaliyle karşılaşır. Bu, kişinin işini kaybetmemesini sağlar. ed
süreç çöküyor. Bu şuna benzer vim
dosyaları değiştir.
Kendi yorumlarımı ekleme özgürlüğünü kullandım. sighup_handler()
Okuyucuya rehberlik etmeye yardımcı olmak için aşağıdaki işlev.
static void sighup_handler(int signum)
{
// [...]
// Listen for SIGHUP signal
if (mutex)
{
sighup_pending = true;
return;
}
sighup_pending = false;
// Hardcode backup filename
const char hb[] = "ed.hup";
// If there are unsaved changes, write current buffer to ed.hup
// in current working directory
if (last_addr() <= 0 || !modified() ||
write_file(hb, "w", 1, last_addr()) >= 0)
exit(0); // Exit here if write was successful
// Otherwise continue executing code and attempt to write to home directory
// Get home directory location from $HOME environment variable
char *const s = getenv("HOME");
// Check if $HOME environment variable is set
if (!s || !s[0])
exit(1);
// Get length of $HOME path
const int len = strlen(s);
// Does $HOME end with a forward slash? 1 if it does, 0 else
const int need_slash = s[len - 1] != '/';
// Construct full path for backup file
char *const hup = (len + need_slash + (int)sizeof hb < path_max(0)) ? (char *)malloc(len + need_slash + sizeof hb) : 0;
// Throw error if path construction fails
if (!hup)
exit(1);
memcpy(hup, s, len);
// Append forward slash to $HOME if missing final forward slash
if (need_slash)
hup[len] = '/';
// Copy backup file contents to
memcpy(hup + len + need_slash, hb, sizeof hb);
// Write contents to
if (write_file(hup, "w", 1, last_addr()) >= 0)
exit(0);
exit(1); /* hup file write failed */
}
Ne yazık ki, kod yorumumda da belirtildiği gibi, yedekleme dosyası her zaman adlandırılacaktır. ed.hup
bu da arzulanan çok şey bırakıyor.
const char hb[] = "ed.hup";
Bunun sorunlara yol açmasının pek çok nedeni var. GNU ise ed
ana dizine veya geçerli dizine yazılamıyor ed.hup
dosya, kullanıcı tüm çalışmalarını kaybedecektir ed
çöküyor. Bunun neden kötü bir fikir olduğunu araştırmak için bir senaryo kullanacağım.
Sudo bana bir sandviç yap
Bu nasıl kullanılacağına dair bir eğitim olmadığından ed
kısaca: yol ed
işe yarayan şey, şunu kullanarak bir arabelleğe satır ekleyebilmenizdir: a
komutunu kullanın ve ardından kullanarak bir dosyaya yazın. w
emretmek. Daha fazlası var ama okuyucunun aşağıda özetlenen her şeyi anlaması için bu yeterli olacaktır.
ed
kullanılarak ana dizinde başlatılır. sudo
ve bir miktar metin ara belleğe yazılır.
❯ ls
❯ sudo ed
a
Writing some text to a buffer using sudo
After the single '.', this process will experience
a SIGHUP signal from a different terminal window
.
141
Bu işlem, kullanılarak adlandırılan bir SIGHUP sinyaliyle karşılaşır. sudo kill -SIGHUP
başka bir terminal penceresinde. ed
arabelleğin içeriğini bir dosyaya yazar ed.hup
geçerli çalışma dizinindeki dosya (ör. $HOME
).
❯ ls -l
total 4
-rw-r--r-- 1 root wheel 141 Feb 7 13:07 ed.hup
❯ cat ed.hup
Writing some text to a buffer using sudo
After the single '.', this process will experience
a SIGHUP signal from a different terminal window
Şimdi bir alt dizine gidiyoruz (örn. demo
) ve kullanarak aynı işlemi tekrarlayın. sudo
ve sebep ed
SIGHUP sinyaliyle karşılaşmak için. O zamandan beri ed
geçerli çalışma dizinini tercih eder $HOME
dizin, ed.hup
geçerli çalışma dizinine yazılacaktır.
demo ❯ ls
total 4
-rw-r--r-- 1 root wheel 141 Feb 7 13:07 ed.hup
demo ❯ cat ed.hup
Writing some text to a buffer using sudo
After the single '.', this process will experience
a SIGHUP signal from a different terminal window
Mevcut dizin yapımız aşağıdaki gibi çalıştırılarak gösterilebilir. tree
ana dizinde.
❯ tree
.
├── ed.hup
└── demo
└── ed.hup
Bu kurulumla nihayet nasıl olduğunu gösterebiliriz ed
sonunda ödevini yemek zorunda kalabilirsin. Alt dizinde başlatın ed
olmadan sudo
ve sürecin çökmesine neden olur.
demo ❯ ed
a
This is my homework for the assignment on Tuesday!
I hope this doesn't get lost. :(
.
ed.hup: Permission denied
/Users//ed.hup: Permission denied
84
demo ❯ ls -l
total 4
-rw-r--r-- 1 root wheel 141 Feb 7 13:07 ed.hup
demo ❯ cat ed.hup
Writing some text to a buffer using sudo
After the single '.', this process will experience
a SIGHUP signal from a different terminal window
demo ❯ cd $HOME
❯ cat ed.hup
Writing some text to a buffer using sudo
After the single '.', this process will experience
a SIGHUP signal from a different terminal window
Az önce tüm ödevlerimizi kaybettik. ed
adresine yazılamadı ed.hup
İşlem gerekli ayrıcalıklara sahip olmadığından, hem geçerli çalışma dizinindeki hem de giriş dizinindeki dosyalar.
Kernighan ve Plauger’in pasajı buraya çok uygun görünüyor.
“Hata düzeltme, editörün tasarımı üzerindeki ikinci büyük etkidir. […]
edit
değerli dosyaları korur, bu nedenle dikkatli olmalıdır. […] Sorunsuz bir şekilde iyileşmesi gerekir, aksi takdirde küçük bir hata değerli bilgilerin kaybına neden olabilir.”— Brian Kernighan ve PJ Plauger, Pascal’da Yazılım Araçları
Bu, statik yedekleme dosya adlarının neden kullanılmaması gerektiğine dair bir derstir.
Güncelleme (Nisan 2022)
- @qrs bağlantı kesildiğinde bir SIGHUP gönderildiğini Twitter’da bana bildirdi; bir süre boyunca değil
ed
kaza. Blog yazımı buna göre güncelledim. - Hacker News kullanıcısı projektfu, kullanıcıların “
sudo -e
yerinesudo $EDITOR
Kök izinleriyle önemli bir şeyi düzenlerken”.