{"componentChunkName":"component---src-templates-blog-post-jsx","path":"/blog/aggregating-rss-feeds-locally-with-a-simple-bash-script/","result":{"data":{"site":{"siteMetadata":{"name":"Huzaifa Rasheed","title":"Huzaifa Rasheed","description":"Software Engineer","about":"\n      Hey, I'm Huzaifa.\n      <br/><br/>\n      Engineer by trade, builder by instinct - I believe in owning my stack, shipping fast, and occasionally running on chai (tea) and stubbornness. I work best in that sweet spot between deep focus and fast feedback - solo or in sync with a good team.\n      <br/><br/>\n      This site's my little corner of the internet - part portfolio, part lab - where I document what I build, break, or learn.\n      <br/><br/>\n      Outside work, I'm into long walks, pixel-perfect headshots in FPS games (eventually... maybe), plants I probably overwater, and the occasional \"classified\" hobby to stay curious.\n      <br/><br/>\n      Reach out anytime - my digital door's always open. 👋\n    ","twitter":"https://twitter.com/huzRasheed","github":"https://github.com/huzaifa-99","linkedin":"https://www.linkedin.com/in/huzaifa-rasheed/","devto":"https://dev.to/huzaifa99","stackoverflow":"https://stackoverflow.com/users/12579290/huzaifa","leetcode":"https://leetcode.com/rhuzaifa","discord":"https://discordapp.com/users/rhuzaifa","email":"dev@rhuzaifa.com","projects":[{"name":"FFMpeg Web","description":"An experimental browser-based terminal that runs FFmpeg using WebAssembly, enabling media processing directly in the browser.","link":"https://ffmpeg-web.rhuzaifa.com/","github":"https://github.com/huzaifa-99/ffmpeg-web"},{"name":"Feed base 2","description":"A mini browser game where players manipulate 4-bit binary blocks to match target BCD values - part puzzle, part binary logic trainer.","link":"https://feedbase2.rhuzaifa.com/","github":"https://github.com/huzaifa-99/feed-base-2"},{"name":"Fabric browser extension","description":"A Chrome extension that injects engineered Fabric prompts directly into the ChatGPT interface for enhanced workflow automation.","link":"https://github.com/huzaifa-99/fabric-browser-extension","github":"https://github.com/huzaifa-99/fabric-browser-extension"},{"name":"Pure Cinema","description":"An experimental, tongue-in-cheek text-to-video generator that stitches together footage, synthesized voiceovers, and background music with a Node.js + ffmpeg pipeline. Not quite Hollywood, but it renders.","link":"https://cinema.rhuzaifa.com","github":null},{"name":"Aria2c Packload","description":"A Bash script for bulk downloading magnet links or torrents using aria2c - optimized for series or list-based transfers.","link":"https://github.com/huzaifa-99/aria2c-packload","github":"https://github.com/huzaifa-99/aria2c-packload"},{"name":"RSS Watchdog","description":"A lightweight Bash script that watches RSS/Atom feeds and compiles a Markdown-based reading checklist for Unix systems.","link":"https://github.com/huzaifa-99/rss-watchdog","github":"https://github.com/huzaifa-99/rss-watchdog"},{"name":"QuoteGen","description":"A quote graphic generator that produces stylized quote images with random selection and a built-in editor for customization.","link":"https://quotegen.rhuzaifa.com/","github":null},{"name":"WebRTC Video Chat","description":"A basic WebRTC-powered app enabling peer-to-peer video and audio calls between two users.","link":"https://webrtc-video-chat.rhuzaifa.com/","github":null}],"experience":null,"skills":[{"name":"Languages & Frameworks","description":"JavaScript, TypeScript, Python, Bash - Frameworks include Node.js, React, Next.js, Vue, React Native, FastAPI."},{"name":"Databases & Storage","description":"PostgreSQL, MySQL, MongoDB - Experience with schema design, indexing, query optimization, and migrations."},{"name":"Cloud & Infrastructure","description":"AWS (EC2, RDS, S3, Lambda), Vercel, Netlify, Heroku - Comfortable with serverless, autoscaling, and cost optimization."},{"name":"DevOps & Tooling","description":"Docker, Git, CI/CD pipelines (GitHub Actions, GitLab CI) - Experience with observability, containerization, and release workflows."},{"name":"Testing & QA Automation","description":"Jest, Playwright, Puppeteer, Selenium - Focus on E2E testing, mocking APIs, and maintaining test coverage."}]}},"markdownRemark":{"id":"3f554b19-9a87-5793-b361-05d8a1269953","excerpt":"Quick backstory: \nMany great RSS readers exist - even open source ones. But I needed something different: a lightweight, cross-platform (Unix) script that pulls…","html":"<p><strong>Quick backstory:</strong><br/>\nMany great RSS readers exist - even open source ones. But I needed something different: a lightweight, cross-platform (Unix) script that pulls content from my RSS subscriptions and turns it into a simple markdown reading checklist, synced locally with my notes.</p>\n<p>Instead of searching endlessly, I wrote one.</p>\n<h3>But why make another tool?</h3>\n<p>I have my reasons</p>\n<ul>\n<li><strong>Unix tools > apps</strong>: Bash outlives every “better” reader.  </li>\n<li><strong>Owning my inputs</strong>: My notes app is my brain. Feeds should flow there.  </li>\n<li><strong>SaaS fatigue</strong>: RSS readers change/decay. Markdown files don’t.  </li>\n</ul>\n<h3>Yeah I went with Bash - Here’s Why</h3>\n<p>I initially started in Python, but quickly pivoted. Bash has two advantages here:</p>\n<ul>\n<li>No special dependencies - I wanted it to work on my Windows and Mac machines</li>\n<li>Works out of the box in almost all Unix-like systems - including headless servers</li>\n</ul>\n<p>It also runs clean on macOS, Linux, WSL, and Git Bash with no extra setup. That made it a better fit for this portable, no-frills script. </p>\n<h3>What does it do?</h3>\n<p>The script pulls feed content into a local file on each run, logging its work, and producing a checklist of reading items in <code class=\"language-text\">markdown</code>.</p>\n<p>It uses only standard tools:\n<code class=\"language-text\">xmllint</code>, <code class=\"language-text\">curl</code>, <code class=\"language-text\">date</code>, <code class=\"language-text\">grep</code> - already included on most systems.</p>\n<p>It works well even in remote cron jobs on home servers, and the output integrates seamlessly into any notes system.</p>\n<p>One catch: the date command behaves slightly differently across Linux vs BSD/macOS. I had to <a href=\"https://github.com/huzaifa-99/rss-watchdog/blob/main/rss_watchdog.sh#L41-L75\">handle that</a> to ensure portable behavior.</p>\n<h3>How to use it?</h3>\n<ol>\n<li>Create a <a href=\"https://github.com/huzaifa-99/rss-watchdog/blob/main/rss_subscriptions.csv\"><code class=\"language-text\">rss_subscriptions.csv</code></a> file with feeds like this:</li>\n</ol>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; margin: 0 0 30px;\"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/87db9ae2b7789abb5da62307a7cb49db/136a2/rss-format.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 16.89189189189189%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAkklEQVQI14WO2wqDMBBE/RBzMSWKkBiTbDT2guD//9N0m771pQ+HGQ7Dsl3YLbx3SCmBiFBrReb+YWG/FWqppIRS6i+dkhqSx8455Ezt8LxkTD5iDoTJRdzmAKkNRN9DCsF78c1f2HeDMdBmaN9d14VSCurzbJTjhe3OPE4Q+zURxvXAGHZM8Wjdugy7FO4V1hPetBdZbRjx07AAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"RSS Subscriptions CSV format\"\n        title=\"RSS Subscriptions CSV format\"\n        src=\"/static/87db9ae2b7789abb5da62307a7cb49db/fcda8/rss-format.png\"\n        srcset=\"/static/87db9ae2b7789abb5da62307a7cb49db/12f09/rss-format.png 148w,\n/static/87db9ae2b7789abb5da62307a7cb49db/e4a3f/rss-format.png 295w,\n/static/87db9ae2b7789abb5da62307a7cb49db/fcda8/rss-format.png 590w,\n/static/87db9ae2b7789abb5da62307a7cb49db/136a2/rss-format.png 884w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">1. `date_subscribed` uses ISO 8601 \n2. You can add any number of feed entries</code></pre></div>\n<ol start=\"2\">\n<li>\n<p>Make the script executable:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token function\">chmod</span> +x ./rss_watchdog.sh</code></pre></div>\n</li>\n<li>\n<p>Run it manually or via cron:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">./rss_watchdog.sh</code></pre></div>\n</li>\n</ol>\n<p>The output lives in:</p>\n<ul>\n<li><code class=\"language-text\">./reading-list.md</code>: Markdown checklist of recent articles</li>\n<li><code class=\"language-text\">./rss_watchdog.log</code>: Script log</li>\n</ul>\n<p>You can change both output paths in the script.</p>\n<h3>What it doesn’t do</h3>\n<p>There’s no feed categorization like typical RSS apps. That was a conscious choice - I just didn’t need it.</p>\n<p>But if you do? You could modify the CSV to include categories and generate multiple checklists accordingly. It’s a flexible base.</p>\n<hr>\n<p>This script is called <a href=\"https://github.com/huzaifa-99/rss-watchdog/blob/main/rss_watchdog.sh\">rss-watchdog</a>.</p>\n<p>It’s simple, portable, and helpful - maybe for you too. If you try it, let me know how it goes.</p>","frontmatter":{"title":"Aggregating RSS Feeds Locally with a Simple Bash Script","date":"July 09, 2024","description":"A portable, dependency-free Bash script to turn RSS/Atom subscriptions into a local markdown reading checklist - great for automation or note-based workflows."}}},"pageContext":{"slug":"/blog/aggregating-rss-feeds-locally-with-a-simple-bash-script/","previous":{"fields":{"slug":"/blog/enhancing-chatgpt-responses-with-fabric-ai-prompts/"},"frontmatter":{"title":"Enhancing ChatGPT Responses with Fabric's AI Prompts"}},"next":{"fields":{"slug":"/blog/one-wildcard-ssl-certificate-to-secure-all-subdomains-via-certbot/"},"frontmatter":{"title":"One Wildcard SSL Certificate to Secure All Subdomains via Certbot"}}}},"staticQueryHashes":["2276319502"]}