<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>emre şahin's digital garden 🍃 - linux</title>
    <link>https://emresahin.net/tags/linux/</link>
    <description>Posts in the linux tag</description>
    <language>en</language>
    <managingEditor>contact@emresahin.net (Emre Şahin)</managingEditor>
    <lastBuildDate>Tue, 15 Sep 2026 19:46:32 +0000</lastBuildDate>
    <atom:link href="https://emresahin.net/tags/linux/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>Find Which Process is Listening on a Port</title>
      <published>2023-03-14T10:45:00+00:00</published>
      <updated>2023-03-14T10:45:00+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Tue, 14 Mar 2023 10:45:00 +0000</pubDate>
      <link>https://emresahin.net/find-which-process-listens-to-a-port/</link>
      <guid isPermaLink="true">https://emresahin.net/find-which-process-listens-to-a-port/</guid>
      <description>Sometimes I need to find out which process is listening on a specific port, usually so I can kill it. On macOS: sudo lsof -i -P | grep LISTEN | grep :$PORT And on Linux: netstat -pntl | grep $PORT</description>
      <category>Bits</category>
      <category>Networking</category>
      <category>SysAdmin</category>
      <category>macos</category>
      <category>linux</category>
      <category>netstat</category>
      <category>lsof</category>
      <category>devops</category>
      <category>terminal</category>
      <content:encoded><![CDATA[<p>Sometimes I need to find out which process is listening on a specific port, usually so I can kill it.</p>
<p>On macOS:</p>
<pre><code class="language-bash">sudo lsof -i -P | grep LISTEN | grep :$PORT
</code></pre>
<p>And on Linux:</p>
<pre><code class="language-bash">netstat -pntl | grep $PORT
</code></pre>]]></content:encoded>
    </item>
    <item>
      <title>bits 11</title>
      <published>2020-12-26T01:07:01+00:00</published>
      <updated>2020-12-26T01:07:01+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Sat, 26 Dec 2020 01:07:01 +0000</pubDate>
      <link>https://emresahin.net/bits-11/</link>
      <guid isPermaLink="true">https://emresahin.net/bits-11/</guid>
      <description>Awk is executed using awk 'awk_program' data-file . Awk programs follow the form pattern { action }; pattern { action }; . BEGIN blocks are executed before reading the data files. END blocks are executed after reading the data files. NR is a variable that indicates the number of records (rows) re...</description>
      <category>shell</category>
      <category>tooling</category>
      <category>awk</category>
      <category>linux</category>
      <category>gawk</category>
      <content:encoded><![CDATA[<ul>
<li>Awk is executed using <code>awk 'awk_program' data-file</code>.</li>
<li>Awk programs follow the form <code>pattern { action }; pattern { action };</code>.</li>
<li><code>BEGIN</code> blocks are executed before reading the data files.</li>
<li><code>END</code> blocks are executed after reading the data files.</li>
<li><code>NR</code> is a variable that indicates the number of records (rows) read so far.</li>
<li><code>-F '&lt;separator&gt;'</code> is used to define a field separator for a file.</li>
<li>A space is the default field separator.</li>
<li><code>FPAT</code> is a regex used to define the pattern for each field.</li>
<li><code>FPAT</code> is specifically defined in Gawk.</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>Zenity</title>
      <published>2018-12-03T18:54:26+00:00</published>
      <updated>2018-12-03T18:54:26+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 03 Dec 2018 18:54:26 +0000</pubDate>
      <link>https://emresahin.net/zenity-14386-18029/</link>
      <guid isPermaLink="true">https://emresahin.net/zenity-14386-18029/</guid>
      <description>When you need a simple dialog to get input from a user or display information in a GUI dialog box, zenity is a great tool. It allows shell scripts to interact with users through various types of dialogs. zenity --info --text="Merge complete. Updated 3 of 10 files."</description>
      <category>shell</category>
      <category>tool</category>
      <category>zenity</category>
      <category>bash</category>
      <category>shell</category>
      <category>linux</category>
      <category>gui</category>
      <content:encoded><![CDATA[<p>When you need a simple dialog to get input from a user or display information in a GUI dialog box, <a href="https://help.gnome.org/users/zenity/3.24/"><code>zenity</code></a> is a great tool. It allows shell scripts to interact with users through various types of dialogs.</p>
<pre><code class="language-bash">zenity --info --text="Merge complete. Updated 3 of 10 files."
</code></pre>
<p><img src="https://emresahin.net/images/zenity-ss.png" alt="zenity-ss"></p>]]></content:encoded>
    </item>
    <item>
      <title>Regular and Recurring Tasks in todo.txt</title>
      <published>2018-02-06T10:23:22+00:00</published>
      <updated>2018-02-06T10:23:22+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Tue, 06 Feb 2018 10:23:22 +0000</pubDate>
      <link>https://emresahin.net/recurrent-todo-txt-14085-74577/</link>
      <guid isPermaLink="true">https://emresahin.net/recurrent-todo-txt-14085-74577/</guid>
      <description>I use the todo.txt format to manage some of my daily tasks. It’s a plain-text format, and both iOS and Android have apps, such as SimpleTasks . Emacs and Vim also support the format. Actually, you don’t need a special editor for it; the format is so simple that even Notepad is sufficient. I have ...</description>
      <category>Productivity</category>
      <category>Automation</category>
      <category>todo.txt</category>
      <category>zsh</category>
      <category>productivity</category>
      <category>cron</category>
      <category>linux</category>
      <content:encoded><![CDATA[<p>I use the <a href="http://todotxt.org/">todo.txt format</a> to manage some of my daily tasks. It’s a
plain-text format, and both iOS and Android have apps, such as
<a href="https://play.google.com/store/apps/details?id=nl.mpcjanssen.todotxtholo">SimpleTasks</a>. <a href="https://github.com/avillafiorita/todotxt-mode">Emacs</a> and <a href="https://github.com/freitass/todo.txt-vim">Vim</a> also support
the format. Actually, you don’t need a special editor for it; the format
is so simple that even Notepad is sufficient.</p>
<p>I have a shell script to add daily recurring tasks, such as “Drink Water” or
“Pray Maghreb,” to this file. SimpleTasks expects the file to be at
<code>$HOME/Dropbox/todo/todo.txt</code>, and I use a template file, such as <code>template.txt</code>,
to populate it. However, as anyone who has used TODO files knows, there are
always unfinished tasks; for instance, I don’t always drink my daily allotted
amount of water.</p>
<p>So, my evening script moves completed tasks (marked as DONE) to their own file,
removes recurring tasks from <code>todo.txt</code>, and repopulates them for a new day.
(Note: The code below is not usable as-is; you must define the <code>TODO</code>, <code>DONE</code>,
and <code>TEMPLATE</code> file paths correctly.)</p>
<pre><code class="language-zsh">
TODO=.../todo.txt
DONE=.../$(date +%F)-done.txt
TEMPLATE=.../template.txt

#Move Done to $DONE
grep -wE '^x ' $TODO &gt;&gt; $DONE
sed -i '/^x /d' $TODO

#Delete lines with @Evening, @Morning or @Regular tags from todo
sed -i "/\b\(@Morning|@Evening|@Regular\)\b/d" $TODO
cat $TODO_TEMPLATE &gt;&gt; $TODO
</code></pre>
<p>I have configured <code>cron</code> to run this every day at 6 PM. (My “evening” starts
earlier than my morning.)</p>]]></content:encoded>
    </item>
    <item>
      <title>zsh'de dosya seçim operatörleri</title>
      <published>2014-03-02T22:00:00+00:00</published>
      <updated>2014-03-02T22:00:00+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Sun, 02 Mar 2014 22:00:00 +0000</pubDate>
      <link>https://emresahin.net/zsh-dosya-operasyonlari/</link>
      <guid isPermaLink="true">https://emresahin.net/zsh-dosya-operasyonlari/</guid>
      <description>zsh, dosya seçmek için bash’ten biraz daha gelişmiş operatörlere sahip. Bunlar sayesinde bir defada bir dizindeki dosyaların tamamına erişip onlar üzerinde işlemler yapmak mümkün. Burada kısa bazı örnekler vereceğim. Bir dizindeki tüm dosyalar: ls * Bulunduğumuz dizin ve tüm alt dizinlerdeki dosy...</description>
      <category>Software Development</category>
      <category>zsh</category>
      <category>shell</category>
      <category>linux</category>
      <category>tutorial</category>
      <content:encoded><![CDATA[<p>zsh, dosya seçmek için bash’ten biraz daha gelişmiş operatörlere sahip. Bunlar sayesinde bir defada bir dizindeki dosyaların tamamına erişip onlar üzerinde işlemler yapmak mümkün. Burada kısa bazı örnekler vereceğim.</p>
<p>Bir dizindeki tüm dosyalar: <code>ls *</code></p>
<p>Bulunduğumuz dizin ve tüm alt dizinlerdeki dosyalar: <code>ls **/*</code></p>
<p>Son iki haftada değiştirilmiş dosyalar: <code>ls **/*(.mw-2)</code></p>
<p>Boyutu 100 MB’tan büyük olan dosyalar: <code>ls **/*(.Lm+100)</code></p>
<p>Sadece okunabilir olan dosyalar: <code>ls **/*(.R)</code></p>
<p><code>/etc</code> dizininde dünya tarafından yazılabilir olan dosyalar: <code>ls /etc/**/*(.W)</code></p>
<p><code>/etc</code> dizininde son bir haftada değiştirilmiş ve dünya tarafından yazılabilir olan dosyalar: <code>ls /etc/**/*(.Wmw-1)</code></p>
<p>zsh’in sağladığı bu gibi seçeneklerin yanında dosya adını parçalamak da kolay. Örneğin dosyanın uzantıdan önceki kısmını almak için <code>*(:r)</code> yazıyoruz. Dizindeki <em>jpg</em> dosyalarını ImageMagick’in <code>convert</code> programıyla aynı isimli png dosyalarına çevirmek şöyle mümkün:</p>
<pre><code class="language-bash">for f in **/*.jpg(.) ; do
   convert ${f:r}.jpg ${f:r}.png
done
</code></pre>
<p>Burada anlatılanları <code>find</code> yoluyla yapmak da mümkün ancak çok daha uzun sürebiliyor. Bilhassa dosya adlarını parçalamak, dönüştürmek gibi işlemleri yaparken zsh’in nimetleri çok. Tek satırlık bir operasyonla çok güçlü bazı dönüşümler yapabilmek mümkün.</p>]]></content:encoded>
    </item>
    <item>
      <title>Backup Script for Recent Files</title>
      <published>2014-02-01T22:00:00+00:00</published>
      <updated>2014-02-01T22:00:00+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Sat, 01 Feb 2014 22:00:00 +0000</pubDate>
      <link>https://emresahin.net/backup-script-for-recent-files/</link>
      <guid isPermaLink="true">https://emresahin.net/backup-script-for-recent-files/</guid>
      <description>I decided to write a script to back up only recent files. There are solutions based on unison that work periodically for all files, but as I change projects, I need to configure new backups for these projects as well. This is cumbersome and error-prone; it is easy to forget to add new artifacts t...</description>
      <category>cli</category>
      <category>tools</category>
      <category>devops</category>
      <category>backup</category>
      <category>rsync</category>
      <category>unison</category>
      <category>bash</category>
      <category>script</category>
      <category>cron</category>
      <category>linux</category>
      <category>automation</category>
      <content:encoded><![CDATA[<p>I decided to write a script to back up only recent files. There are solutions based on <a href="http://www.cis.upenn.edu/~bcpierce/unison/">unison</a> that work periodically for all files, but as I change projects, I need to configure new backups for these projects as well. This is cumbersome and error-prone; it is easy to forget to add new artifacts to backup scripts and lose them in an emergency.</p>
<p>Therefore, I decided that a small Bash script using <a href="http://rsync.samba.org/">rsync</a> and <a href="http://en.wikipedia.org/wiki/Find">find</a> would work better. It monitors my entire home directory and backs up recent files.</p>
<p>The following script does exactly that:</p>
<pre><code class="language-bash">#!/bin/bash

if [ "x$1" = "x" ] ; then
    TARGET=/media/augustus/backup-recent-`hostname`
else
    TARGET=$1
fi

PERIOD=15

mkdir -p $TARGET

# Delete files older than $PERIOD days
find $TARGET -ctime +$PERIOD -print -delete

# Copy files newer than $PERIOD under ~. Ignore files under .hg
for d in ~/*/ ; do
    find $d -path '*/.hg/*' -prune -o -type f -ctime -$PERIOD -print  -exec rsync -aRv {} $TARGET/ \;
done
</code></pre>
<p>It checks whether a command-line option is provided as the target; otherwise, it sets a default target. <code>/media/augustus/</code> is an NFS mount in my case, but you can specify any path.</p>
<p><code>PERIOD</code> is the number of days that the script considers <em>recent</em>. Currently, it backs up files changed in the last 15 days.</p>
<p>The script deletes older files from the backup. Since I use other solutions for long-term storage, I don’t want to keep them here, especially since this script runs via <code>cron</code> every two hours.</p>
<p>Note that the script only checks directories under the home directory, so files located directly in the home directory are not backed up.</p>
<p>It also skips files under <code>.hg</code> directories. You can add more <code>-prune</code> options to the <code>find</code> command to exclude other irrelevant directories from your backup.</p>]]></content:encoded>
    </item>
    <item>
      <title>Midori</title>
      <published>2013-01-16T14:00:00+00:00</published>
      <updated>2013-01-16T14:00:00+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Wed, 16 Jan 2013 14:00:00 +0000</pubDate>
      <link>https://emresahin.net/12239-10-865/</link>
      <guid isPermaLink="true">https://emresahin.net/12239-10-865/</guid>
      <description>My browser of choice used to be Google Chrome, but the latest versions have become resource hogs, and I was feeling this on my older machines. I decided to take a look at alternative browsers and settled on Midori . I turned off JavaScript ( the best JS is dead JS ), enabled ad blocking, and cust...</description>
      <category>Web</category>
      <category>Software</category>
      <category>browsers</category>
      <category>midori</category>
      <category>JavaScript</category>
      <category>keyboard</category>
      <category>Linux</category>
      <category>open source</category>
      <content:encoded><![CDATA[<p>My browser of choice used to be Google Chrome, but the latest versions have become
resource hogs, and I was feeling this on my older machines. I decided to
take a look at alternative browsers and settled on
<a href="http://twotoasts.de/index.php/midori/">Midori</a>.</p>
<p>I turned off JavaScript (<em>the best JS is dead JS</em>), enabled ad blocking,
and customized keyboard shortcuts (changing <em>Ctrl-F</em> to <em>Ctrl-S</em> as in Emacs).
It loads noticeably faster, and I can’t even tell how many tabs are open
while using other applications.</p>
<p>If you’re using Linux, it’s likely in your distribution’s repository. If
you’re on Windows, the <a href="http://twotoasts.de/index.php/midori/">Midori home
page</a> provides both installable
and portable packages.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
