2023-01-16 11:51:46 +01:00
<!DOCTYPE html>
2023-01-16 05:05:23 +01:00
<!--
Minimal Mistakes Jekyll Theme 4.24.0 by Michael Rose
Copyright 2013-2020 Michael Rose - mademistakes.com | @mmistakes
Free for personal and commercial use under the MIT license
https://github.com/mmistakes/minimal-mistakes/blob/master/LICENSE
2023-01-16 11:51:46 +01:00
-->< html lang = "en" class = "no-js" >
2023-01-16 05:05:23 +01:00
< head >
2023-01-16 11:51:46 +01:00
< meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
2023-01-16 05:05:23 +01:00
< meta charset = "utf-8" >
<!-- begin _includes/seo.html --> < title > Hot-Reload Long Running Shell Scripts (feat. trap / kill) - Şahin Akkaya’ s Personal Page< / title >
2023-01-16 11:51:46 +01:00
< meta name = "description" content = "trap them and kill them! There is a beautiful command in Linux called trap which traps signals and let you run specific commands when they invoked. There is also good ol’ kill command which not only kills processes but allows you to specify a signal to send. By combining these two, you can run specific functions from your scripts any time!" >
2023-01-16 05:05:23 +01:00
< meta name = "author" content = "Şahin Akkaya" >
< meta property = "article:author" content = "Şahin Akkaya" >
< meta property = "og:type" content = "article" >
< meta property = "og:locale" content = "en_US" >
< meta property = "og:site_name" content = "Şahin Akkaya's Personal Page" >
< meta property = "og:title" content = "Hot-Reload Long Running Shell Scripts (feat. trap / kill)" >
< meta property = "og:url" content = "https://sahinakkaya.dev/2023/01/15/hot-reloading-with-trap-and-kill.html" >
2023-01-16 11:51:46 +01:00
< meta property = "og:description" content = "trap them and kill them! There is a beautiful command in Linux called trap which traps signals and let you run specific commands when they invoked. There is also good ol’ kill command which not only kills processes but allows you to specify a signal to send. By combining these two, you can run specific functions from your scripts any time!" >
2023-01-16 05:05:23 +01:00
< meta property = "article:published_time" content = "2023-01-15T21:48:08+00:00" >
< link rel = "canonical" href = "https://sahinakkaya.dev/2023/01/15/hot-reloading-with-trap-and-kill.html" >
< script type = "application/ld+json" >
{
"@context": "https://schema.org",
"@type": "Person",
"name": null,
"url": "https://sahinakkaya.dev/"
}
< / script >
<!-- end _includes/seo.html -->
< link href = "/feed.xml" type = "application/atom+xml" rel = "alternate" title = "Şahin Akkaya's Personal Page Feed" >
<!-- https://t.co/dKP3o1e -->
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< script >
document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/g, '') + ' js ';
< / script >
<!-- For all browsers -->
< link rel = "stylesheet" href = "/assets/css/main.css" >
< link rel = "preload" href = "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5/css/all.min.css" as = "style" onload = "this.onload=null;this.rel='stylesheet'" >
< noscript > < link rel = "stylesheet" href = "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5/css/all.min.css" > < / noscript >
<!-- start custom head snippets -->
<!-- insert favicons. use https://realfavicongenerator.net/ -->
<!-- end custom head snippets -->
< / head >
< body class = "layout--single" >
< nav class = "skip-links" >
< ul >
< li > < a href = "#site-nav" class = "screen-reader-shortcut" > Skip to primary navigation< / a > < / li >
< li > < a href = "#main" class = "screen-reader-shortcut" > Skip to content< / a > < / li >
< li > < a href = "#footer" class = "screen-reader-shortcut" > Skip to footer< / a > < / li >
< / ul >
< / nav >
<!-- [if lt IE 9]>
< div class = "notice--danger align-center" style = "margin: 0;" > You are using an < strong > outdated< / strong > browser. Please < a href = "https://browsehappy.com/" > upgrade your browser< / a > to improve your experience.< / div >
<![endif]-->
< div class = "masthead" >
< div class = "masthead__inner-wrap" >
< div class = "masthead__menu" >
< nav id = "site-nav" class = "greedy-nav" >
< a class = "site-title" href = "/" >
/home/sahin/
< / a >
2023-01-16 11:51:46 +01:00
< ul class = "visible-links" >
< li class = "masthead__menu-item" >
2023-01-16 05:05:23 +01:00
< a href = "/" > Home< / a >
2023-01-16 11:51:46 +01:00
< / li >
< li class = "masthead__menu-item" >
2023-01-16 05:05:23 +01:00
< a href = "/about/" > About< / a >
2023-01-16 11:51:46 +01:00
< / li >
< li class = "masthead__menu-item" >
2023-01-16 05:05:23 +01:00
< a href = "/contact/" > Contact< / a >
2023-01-16 11:51:46 +01:00
< / li >
< / ul >
2023-01-16 05:05:23 +01:00
< button class = "search__toggle" type = "button" >
< span class = "visually-hidden" > Toggle search< / span >
< i class = "fas fa-search" > < / i >
< / button >
< button class = "greedy-nav__toggle hidden" type = "button" >
< span class = "visually-hidden" > Toggle menu< / span >
< div class = "navicon" > < / div >
< / button >
< ul class = "hidden-links hidden" > < / ul >
< / nav >
< / div >
< / div >
< / div >
< div class = "initial-content" >
< div id = "main" role = "main" >
< div class = "sidebar sticky" >
< div itemscope itemtype = "https://schema.org/Person" >
< div class = "author__avatar" >
< img src = "/assets/images/logo.jpg" alt = "Şahin Akkaya" itemprop = "image" >
< / div >
< div class = "author__content" >
< h3 class = "author__name" itemprop = "name" > Şahin Akkaya< / h3 >
< div class = "author__bio" itemprop = "description" >
< p > A perfectionist who likes to tinker everything until it is just right.< / p >
< / div >
< / div >
< div class = "author__urls-wrapper" >
< button class = "btn btn--inverse" > Follow< / button >
< ul class = "author__urls social-icons" >
< li itemprop = "homeLocation" itemscope itemtype = "https://schema.org/Place" >
< i class = "fas fa-fw fa-map-marker-alt" aria-hidden = "true" > < / i > < span itemprop = "name" > Istanbul, Turkey< / span >
< / li >
2023-01-16 11:51:46 +01:00
< li > < a href = "https://github.com/sahinakkaya" rel = "nofollow noopener noreferrer" > < i class = "fab fa-fw fa-github" aria-hidden = "true" > < / i > < span class = "label" > sahinakkayadev< / span > < / a > < / li >
2023-01-16 05:05:23 +01:00
< li > < a href = "https://stackoverflow.com/users/9608759" rel = "nofollow noopener noreferrer" > < i class = "fab fa-fw fa-stack-overflow" aria-hidden = "true" > < / i > < span class = "label" > Asocia< / span > < / a > < / li >
< li > < a href = "https://twitter.com/sahinakkayadev" rel = "nofollow noopener noreferrer" > < i class = "fab fa-fw fa-twitter-square" aria-hidden = "true" > < / i > < span class = "label" > @sahinakkayadev< / span > < / a > < / li >
< li > < a href = "mailto:sahin@sahinakkaya.dev" rel = "nofollow noopener noreferrer" > < i class = "fas fa-fw fa-envelope" aria-hidden = "true" > < / i > < span class = "label" > sahin@sahinakkaya.dev< / span > < / a > < / li >
< li > < a href = "/assets/docs/resume.pdf" rel = "nofollow noopener noreferrer" > < i class = "fas fa-fw fa-id-card" aria-hidden = "true" > < / i > < span class = "label" > Resume< / span > < / a > < / li >
<!--
< li >
< a href = "http://link-to-whatever-social-network.com/user/" itemprop = "sameAs" rel = "nofollow noopener noreferrer" >
< i class = "fas fa-fw" aria-hidden = "true" > < / i > Custom Social Profile Link
< / a >
< / li >
-->
< / ul >
< / div >
< / div >
< / div >
< article class = "page" itemscope itemtype = "https://schema.org/CreativeWork" >
< meta itemprop = "headline" content = "Hot-Reload Long Running Shell Scripts (feat. trap / kill)" >
2023-01-16 11:51:46 +01:00
< meta itemprop = "description" content = "trap them and kill them!There is a beautiful command in Linux called trap which traps signals and let you run specific commands when they invoked. There is also good ol’ kill command which not only kills processes but allows you to specify a signal to send. By combining these two, you can run specific functions from your scripts any time!" >
2023-01-16 05:05:23 +01:00
< meta itemprop = "datePublished" content = "2023-01-15T21:48:08+00:00" >
< div class = "page__inner-wrap" >
< header >
< h1 id = "page-title" class = "page__title" itemprop = "headline" > Hot-Reload Long Running Shell Scripts (feat. trap / kill)
< / h1 >
< p class = "page__meta" >
< span class = "page__meta-date" >
< i class = "far fa-calendar-alt" aria-hidden = "true" > < / i >
< time datetime = "2023-01-15T21:48:08+00:00" > January 15, 2023< / time >
< / span >
< span class = "page__meta-sep" > < / span >
< span class = "page__meta-readtime" >
< i class = "far fa-clock" aria-hidden = "true" > < / i >
5 minute read
< / span >
< / p >
< / header >
< section class = "page__content" itemprop = "text" >
2023-01-16 11:51:46 +01:00
< h2 id = "trap-them-and-kill-them" >
< code class = "language-plaintext highlighter-rouge" > trap< / code > them and < code class = "language-plaintext highlighter-rouge" > kill< / code > them!< / h2 >
2023-01-16 05:05:23 +01:00
< p > There is a beautiful command in Linux called < a href = "https://man7.org/linux/man-pages/man1/trap.1p.html" > < code class = "language-plaintext highlighter-rouge" > trap< / code > < / a > which < em > trap< / em > s signals and let you run specific commands when they invoked. There is also good ol’ < a href = "https://man7.org/linux/man-pages/man1/kill.1.html" > < code class = "language-plaintext highlighter-rouge" > kill< / code > < / a > command which not only kills processes but allows you to specify a signal to send. By combining these two, you can run specific functions from your scripts any time!< / p >
< h3 id = "basic-example" > Basic Example< / h3 >
< p > Let’ s start by creating something very simple and build up from there. Create a script with the following contents:< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > < span class = "c" > #!/bin/bash< / span >
< span class = "nb" > echo< / span > < span class = "s2" > "My pid is < / span > < span class = "nv" > $$< / span > < span class = "s2" > . Send me SIGUSR1!"< / span >
func< span class = "o" > ()< / span > < span class = "o" > {< / span >
< span class = "nb" > echo< / span > < span class = "s2" > "Got SIGUSR1"< / span >
< span class = "o" > }< / span >
2023-01-16 05:36:45 +01:00
< span class = "c" > # here we are telling that run 'func' when USR1 signal is< / span >
< span class = "c" > # received. You can run anything. Combine commands with ; etc.< / span >
2023-01-16 05:05:23 +01:00
< span class = "nb" > trap< / span > < span class = "s2" > "func"< / span > USR1
< span class = "c" > # The while loop is important here otherwise our script will exit< / span >
< span class = "c" > # before we manage to get a chance to send a signal.< / span >
< span class = "k" > while < / span > < span class = "nb" > true< / span > < span class = "p" > ;< / span > < span class = "k" > do
< / span > < span class = "nb" > echo< / span > < span class = "s2" > "waiting SIGUSR1"< / span >
< span class = "nb" > sleep < / span > 1
< span class = "k" > done< / span >
< / code > < / pre > < / div > < / div >
< p > Now make it executable and run it:< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ❯ < span class = "nb" > chmod< / span > +x trap_example
❯ ./trap_example
My pid is 2811137. Send me SIGUSR1!
waiting SIGUSR1
waiting SIGUSR1
waiting SIGUSR1
waiting SIGUSR1
waiting SIGUSR1
< / code > < / pre > < / div > < / div >
< p > Open another terminal and send your signal with < code class = "language-plaintext highlighter-rouge" > kill< / code > to the specified pid.< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ❯ < span class = "nb" > kill< / span > < span class = "nt" > -s< / span > USR1 2811137
< / code > < / pre > < / div > < / div >
< p > You should receive < code class = "language-plaintext highlighter-rouge" > "Got SIGUSR!"< / code > from the other process. That’ s it! Now, imagine you write whatever thing you want to execute in < code class = "language-plaintext highlighter-rouge" > func< / code > and then you can simply < code class = "language-plaintext highlighter-rouge" > kill -s ...< / code > anytime and as many times you want!< / p >
< p > Let’ s move the while loop into the < code class = "language-plaintext highlighter-rouge" > func< / code > and add some variables so you can see how powerful this is.< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > < span class = "c" > #!/bin/bash< / span >
< span class = "nb" > echo< / span > < span class = "s2" > "My pid is < / span > < span class = "nv" > $$< / span > < span class = "s2" > . Send me SIGUSR1!"< / span >
func< span class = "o" > ()< / span > < span class = "o" > {< / span >
< span class = "nv" > i< / span > < span class = "o" > =< / span > 1
< span class = "k" > while < / span > < span class = "nb" > true< / span > < span class = "p" > ;< / span > < span class = "k" > do
< / span > < span class = "nb" > echo< / span > < span class = "s2" > "i: < / span > < span class = "nv" > $i< / span > < span class = "s2" > "< / span >
< span class = "nv" > i< / span > < span class = "o" > =< / span > < span class = "k" > $((< / span > i < span class = "o" > +< / span > < span class = "m" > 1< / span > < span class = "k" > ))< / span >
< span class = "nb" > sleep < / span > 1
< span class = "k" > done< / span >
< span class = "o" > }< / span >
< span class = "nb" > trap< / span > < span class = "s2" > "echo 'Got SIGUSR1!'; func"< / span > USR1
< span class = "c" > # we need to call the function once, otherwise script< / span >
< span class = "c" > # will exit before we manage to send a signal< / span >
func
< / code > < / pre > < / div > < / div >
< p > Now run the script and send < code class = "language-plaintext highlighter-rouge" > SIGUSR1< / code > . Here is the result:< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ❯ ./trap_example
My pid is 2880704. Send me SIGUSR1!
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
Got SIGUSR1!
i: 1
i: 2
i: 3
i: 4
i: 5
Got SIGUSR1!
i: 1
i: 2
^C
< / code > < / pre > < / div > < / div >
< p > Isn’ t this neat?< / p >
< h3 id = "more-useful-example" > More useful example< / h3 >
< p > Let’ s imagine you have multiple long running (infinite loops basically) scripts and you want to restart them without manually searching for their pid’ s and killing them. < code class = "language-plaintext highlighter-rouge" > trap< / code > is for the rescue, again! < sup > < a href = "##" title = "Yeah, I know you can run a systemd service if you want but I think it is an overkill for this situation. Plus, I don't like dealing with them." > *< / a > < / sup > This command is awesome.< / p >
< p > Without further ado, let’ s get started. Create a script called < code class = "language-plaintext highlighter-rouge" > script1< / code > with the following contents:< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > < span class = "c" > #!/bin/bash< / span >
< span class = "c" > # file: script1< / span >
< span class = "nv" > i< / span > < span class = "o" > =< / span > 1
< span class = "k" > while < / span > < span class = "nb" > true< / span > < span class = "p" > ;< / span > < span class = "k" > do
< / span > < span class = "nb" > echo< / span > < span class = "s2" > "Hello from < / span > < span class = "nv" > $0< / span > < span class = "s2" > . i is < / span > < span class = "nv" > $i< / span > < span class = "s2" > "< / span >
< span class = "nv" > i< / span > < span class = "o" > =< / span > < span class = "k" > $((< / span > i < span class = "o" > +< / span > < span class = "m" > 1< / span > < span class = "k" > ))< / span >
< span class = "nb" > sleep < / span > 1
< span class = "k" > done< / span >
< / code > < / pre > < / div > < / div >
< p > And symlink it to another name just for fun:< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ❯ < span class = "nb" > chmod< / span > +x script1
❯ < span class = "nb" > ln< / span > < span class = "nt" > -s< / span > script1 script2
< / code > < / pre > < / div > < / div >
< p > Now we can pretend they are two different scripts as their outputs differ:< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ❯ ./script1
Hello from ./script1. i is 1
Hello from ./script1. i is 2
Hello from ./script1. i is 3
Hello from ./script1. i is 4
^C
❯ ./script2
Hello from ./script2. i is 1
Hello from ./script2. i is 2
Hello from ./script2. i is 3
^C
< / code > < / pre > < / div > < / div >
< p > Finally, create the main script which will start child scripts and restart them on our signals:< / p >
< div class = "language-bash highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > < span class = "c" > #!/bin/bash< / span >
< span class = "nb" > echo< / span > < span class = "s2" > "My pid is < / span > < span class = "nv" > $$< / span > < span class = "s2" > . You know what to do ( ͡° ͜ʖ ͡°)"< / span >
< span class = "nb" > echo< / span > < span class = "s2" > "You can also send me signal with 'killall < / span > < span class = "sb" > `< / span > < span class = "nb" > basename< / span > < span class = "nv" > $0< / span > < span class = "sb" > `< / span > < span class = "s2" > ...'"< / span >
< span class = "nv" > pids< / span > < span class = "o" > =()< / span > < span class = "c" > # we will store the pid's of child scripts here< / span >
< span class = "nv" > scripts_to_be_executed< / span > < span class = "o" > =(< / span > < span class = "s2" > "./script1"< / span > < span class = "s2" > "./script2"< / span > < span class = "o" > )< / span >
kill_childs< span class = "o" > (){< / span > < span class = "c" > # wow, this sounded wild< / span >
< span class = "k" > for < / span > pid < span class = "k" > in< / span > < span class = "s2" > "< / span > < span class = "k" > ${< / span > < span class = "nv" > pids< / span > < span class = "p" > [@]< / span > < span class = "k" > }< / span > < span class = "s2" > "< / span >
< span class = "k" > do
< / span > < span class = "nb" > echo < / span > killing < span class = "s2" > "< / span > < span class = "nv" > $pid< / span > < span class = "s2" > "< / span >
< span class = "nb" > kill< / span > < span class = "s2" > "< / span > < span class = "nv" > $pid< / span > < span class = "s2" > "< / span >
< span class = "k" > done
< / span > < span class = "nv" > pids< / span > < span class = "o" > =()< / span >
< span class = "o" > }< / span >
< span class = "c" > # kill childs and restart all the scripts< / span >
restart_scripts< span class = "o" > (){< / span >
kill_childs
< span class = "c" > # for each script in the list< / span >
< span class = "k" > for < / span > script < span class = "k" > in< / span > < span class = "s2" > "< / span > < span class = "k" > ${< / span > < span class = "nv" > scripts_to_be_executed< / span > < span class = "p" > [@]< / span > < span class = "k" > }< / span > < span class = "s2" > "< / span >
< span class = "k" > do< / span >
2023-01-16 16:57:32 +01:00
< span class = "c" > # Run the script and store its pid.< / span >
< span class = "c" > # note the '& ' at the end of command. Without it the script will< / span >
< span class = "c" > # block until its execution is finished. Also we are putting it< / span >
< span class = "c" > # into braces because we want to create a process group so that< / span >
< span class = "c" > # killing this pid will end all the grandchilds.< / span >
< span class = "c" > # (useful if you have pipes (|) or other & 's in your script!)< / span >
< span class = "o" > (< / span > < span class = "nv" > $script< / span > < span class = "o" > )< / span > &
pids+< span class = "o" > =(< / span > < span class = "s2" > "< / span > < span class = "nv" > $!< / span > < span class = "s2" > "< / span > < span class = "o" > )< / span >
2023-01-16 05:05:23 +01:00
< span class = "k" > done< / span >
< span class = "o" > }< / span >
< span class = "c" > # we will restart_scripts with SIGUSR1 signal< / span >
< span class = "nb" > trap< / span > < span class = "s1" > 'echo "restarting scripts"; restart_scripts'< / span > USR1
< span class = "c" > # we will kill all the childs and exit the main script with SIGINT< / span >
< span class = "c" > # which is same signal as when you press < Control-C> on your terminal< / span >
< span class = "nb" > trap< / span > < span class = "s1" > 'echo exiting; kill_childs; exit'< / span > INT
< span class = "c" > # run the function once< / span >
restart_scripts
< span class = "c" > # infinite loop, otherwise main script will exit before we send signal.< / span >
< span class = "c" > # remember, we started child processes with '& ' so they won't block this script< / span >
< span class = "k" > while < / span > < span class = "nb" > true< / span > < span class = "p" > ;< / span > < span class = "k" > do
< / span > < span class = "nb" > sleep < / span > 1
< span class = "k" > done< / span >
< / code > < / pre > < / div > < / div >
< p > Now, you can run your main script and reload your child scripts any time with < code class = "language-plaintext highlighter-rouge" > killall main_script -USR1< / code > < / p >
< p > Here is an example run:< / p >
< div class = "language-plaintext highlighter-rouge" > < div class = "highlight" > < pre class = "highlight" > < code > ❯ ./trap_multiple
My pid is 3124123. You know what to do ( ͡° ͜ʖ ͡°)
You can also send me signal with 'killall trap_multiple ...'
Hello from ./script1. i is 1
Hello from ./script2. i is 1
Hello from ./script2. i is 2
Hello from ./script1. i is 2
Hello from ./script2. i is 3
Hello from ./script1. i is 3
restarting scripts
killing 3124125
killing 3124126
Hello from ./script1. i is 1
Hello from ./script2. i is 1
Hello from ./script2. i is 2
Hello from ./script1. i is 2
Hello from ./script2. i is 3
Hello from ./script1. i is 3
Hello from ./script2. i is 4
Hello from ./script1. i is 4
restarting scripts
killing 3124304
killing 3124305
Hello from ./script1. i is 1
Hello from ./script2. i is 1
Hello from ./script1. i is 2
Hello from ./script2. i is 2
^Cexiting
killing 3124875
killing 3124876
< / code > < / pre > < / div > < / div >
< h3 id = "final-words" > Final words< / h3 >
2023-01-16 11:27:38 +01:00
< p > I think I am started to getting obsessed with < code class = "language-plaintext highlighter-rouge" > trap< / code > command because it has such a good name and purpose. FOSS people are really on another level when it comes to naming. Here is another good one:< / p >
2023-01-16 05:05:23 +01:00
< blockquote >
2023-01-16 11:51:46 +01:00
< p > - How can you see the contents of a file? < br >
+ You < em > < code class = "language-plaintext highlighter-rouge" > cat< / code > < / em > it. < br >
- What if you want to see them in reverse order? < br >
+ You < em > < code class = "language-plaintext highlighter-rouge" > tac< / code > < / em > it. < br > < / p >
2023-01-16 05:05:23 +01:00
< / blockquote >
< p > No, it is not just a joke. Try it… Man I love Gnoo slash Linux.< / p >
2023-01-16 05:36:45 +01:00
< p > Anyway, I hope now you know how to < code class = "language-plaintext highlighter-rouge" > trap< / code > and < code class = "language-plaintext highlighter-rouge" > kill< / code > . Next week I will explain how to < code class = "language-plaintext highlighter-rouge" > unzip; strip; touch; finger; grep; mount; fsck; more; yes; fsck; fsck; umount; clean; sleep< / code > < nobr > ( ͡° ͜ʖ ͡°)< / nobr > . < sup > < a href = "##" title = "jk :D" > *< / a > < / sup > < / p >
2023-01-16 05:05:23 +01:00
< / section >
< footer class = "page__meta" >
< p class = "page__date" > < strong > < i class = "fas fa-fw fa-calendar-alt" aria-hidden = "true" > < / i > Updated:< / strong > < time datetime = "2023-01-15T21:48:08+00:00" > January 15, 2023< / time > < / p >
< / footer >
2023-01-16 11:51:46 +01:00
2023-01-16 05:05:23 +01:00
< nav class = "pagination" >
< a href = "/2022/12/29/recap-of-2022.html" class = "pagination--pager" title = "Recap of 2022
">Previous< / a >
< a href = "#" class = "pagination--pager disabled" > Next< / a >
< / nav >
< / div >
< / article >
< div class = "page__related" >
< h4 class = "page__related-title" > You May Also Enjoy< / h4 >
< div class = "grid__wrapper" >
< div class = "grid__item" >
< article class = "archive__item" itemscope itemtype = "https://schema.org/CreativeWork" >
< h2 class = "archive__item-title no_toc" itemprop = "headline" >
< a href = "/2022/12/29/recap-of-2022.html" rel = "permalink" > Recap of 2022
< / a >
< / h2 >
< p class = "page__meta" >
< span class = "page__meta-date" >
< i class = "far fa-fw fa-calendar-alt" aria-hidden = "true" > < / i >
< time datetime = "2022-12-29T20:22:08+00:00" > December 29, 2022< / time >
< / span >
< span class = "page__meta-sep" > < / span >
< span class = "page__meta-readtime" >
< i class = "far fa-fw fa-clock" aria-hidden = "true" > < / i >
1 minute read
< / span >
< / p >
< p class = "archive__item-excerpt" itemprop = "description" > It’ s been a while… It has been so long that I forgot how I was writing my blogs back then. My life didn’ t change that much. Actually, it is getting worse.
< / p >
< / article >
< / div >
< div class = "grid__item" >
< article class = "archive__item" itemscope itemtype = "https://schema.org/CreativeWork" >
< h2 class = "archive__item-title no_toc" itemprop = "headline" >
< a href = "/2022/06/22/rant-on-peoples-reaction-to-copilot.html" rel = "permalink" > Rant: Stop whatever you are doing and learn how licenses work
< / a >
< / h2 >
< p class = "page__meta" >
< span class = "page__meta-date" >
< i class = "far fa-fw fa-calendar-alt" aria-hidden = "true" > < / i >
< time datetime = "2022-06-22T07:46:00+00:00" > June 22, 2022< / time >
< / span >
< span class = "page__meta-sep" > < / span >
< span class = "page__meta-readtime" >
< i class = "far fa-fw fa-clock" aria-hidden = "true" > < / i >
2 minute read
< / span >
< / p >
< p class = "archive__item-excerpt" itemprop = "description" > Recently, Github announced
that they are making Github Copilot available for everyone. Previously, it was in Beta and you could get it through the waiting l...< / p >
< / article >
< / div >
< div class = "grid__item" >
< article class = "archive__item" itemscope itemtype = "https://schema.org/CreativeWork" >
< h2 class = "archive__item-title no_toc" itemprop = "headline" >
< a href = "/2022/04/08/confession-time.html" rel = "permalink" > Confession Time
< / a >
< / h2 >
< p class = "page__meta" >
< span class = "page__meta-date" >
< i class = "far fa-fw fa-calendar-alt" aria-hidden = "true" > < / i >
< time datetime = "2022-04-08T15:46:00+00:00" > April 8, 2022< / time >
< / span >
< span class = "page__meta-sep" > < / span >
< span class = "page__meta-readtime" >
< i class = "far fa-fw fa-clock" aria-hidden = "true" > < / i >
2 minute read
< / span >
< / p >
< p class = "archive__item-excerpt" itemprop = "description" > A failure story
Last week, I received an email from Let’ s Encrypt reminding me to renew my certificates. I forgot to renew it and the certificate expired. No...< / p >
< / article >
< / div >
< div class = "grid__item" >
< article class = "archive__item" itemscope itemtype = "https://schema.org/CreativeWork" >
< h2 class = "archive__item-title no_toc" itemprop = "headline" >
< a href = "/2022/03/03/never-get-trapped-in-grub-rescue-again.html" rel = "permalink" > Never Get Trapped in Grub Rescue Again!
< / a >
< / h2 >
< p class = "page__meta" >
< span class = "page__meta-date" >
< i class = "far fa-fw fa-calendar-alt" aria-hidden = "true" > < / i >
< time datetime = "2022-03-03T00:46:00+00:00" > March 3, 2022< / time >
< / span >
< span class = "page__meta-sep" > < / span >
< span class = "page__meta-readtime" >
< i class = "far fa-fw fa-clock" aria-hidden = "true" > < / i >
4 minute read
< / span >
< / p >
< p class = "archive__item-excerpt" itemprop = "description" > Anytime I install a new system on my machine, I pray God for nothing bad happens. But it usually happens. When I reboot, I find myself in the “Grub rescue” m...< / p >
< / article >
< / div >
< / div >
< / div >
< / div >
< / div >
< div class = "search-content" >
2023-01-16 11:51:46 +01:00
< div class = "search-content__inner-wrap" >
< form class = "search-content__form" onkeydown = "return event.key != 'Enter';" >
2023-01-16 05:05:23 +01:00
< label class = "sr-only" for = "search" >
Enter your search term...
< / label >
2023-01-16 11:51:46 +01:00
< input type = "search" id = "search" class = "search-input" tabindex = "-1" placeholder = "Enter your search term..." >
2023-01-16 05:05:23 +01:00
< / form >
2023-01-16 11:51:46 +01:00
< div id = "results" class = "results" > < / div >
< / div >
2023-01-16 05:05:23 +01:00
< / div >
< div id = "footer" class = "page__footer" >
< footer >
<!-- start custom footer snippets -->
<!-- end custom footer snippets -->
< div class = "page__footer-follow" >
< ul class = "social-icons" >
< li > < a href = "/feed.xml" > < i class = "fas fa-fw fa-rss-square" aria-hidden = "true" > < / i > Feed< / a > < / li >
< / ul >
< / div >
2023-01-16 11:51:46 +01:00
< div class = "page__footer-copyright" > © 2023 Şahin Akkaya's Personal Page. Powered by < a href = "https://jekyllrb.com" rel = "nofollow" > Jekyll< / a > & < a href = "https://mademistakes.com/work/minimal-mistakes-jekyll-theme/" rel = "nofollow" > Minimal Mistakes< / a > .< / div >
2023-01-16 05:05:23 +01:00
< div class = "page__footer-copyright" >
Check out the < a href = "https://github.com/Asocia/sahinakkayadotdev" > code< / a > of this site.
< / div >
< / footer >
< / div >
< script src = "/assets/js/main.min.js" > < / script >
< script src = "/assets/js/lunr/lunr.min.js" > < / script >
< script src = "/assets/js/lunr/lunr-store.js" > < / script >
< script src = "/assets/js/lunr/lunr-en.js" > < / script >
< / body >
< / html >