{"id":15905,"date":"2019-06-17T14:29:09","date_gmt":"2019-06-17T14:29:09","guid":{"rendered":"https:\/\/www.bartbusschots.ie\/s\/?p=15905"},"modified":"2019-09-26T00:32:25","modified_gmt":"2019-09-26T00:32:25","slug":"moving-my-bashrc-to-zshrc","status":"publish","type":"post","link":"https:\/\/www.bartbusschots.ie\/s\/2019\/06\/17\/moving-my-bashrc-to-zshrc\/","title":{"rendered":"Moving my .bashrc to .zshrc"},"content":{"rendered":"<div class=\"pps-series-post-details pps-series-post-details-variant-classic pps-series-post-details-18702\" data-series-id=\"581\"><div class=\"pps-series-meta-content\"><div class=\"pps-series-meta-text\">This entry is part 6 of 6 in the series <a href=\"https:\/\/www.bartbusschots.ie\/s\/series\/bash-to-zsh\/\">Bash to Zsh<\/a><\/div><\/div><\/div><p>Having used Zsh rather than Bash for over a week it was time to make the move permanent by migrating my shell customisations from <code>~\/.bashrc<\/code> to <code>~\/.zshrc<\/code>. Your milage may vary, but I was pleased to find I didn&#8217;t need to make any changes, and, that I could get rid of one command from the script because Zsh defaults to a behaviour I had to explicitly opt in to with Bash.<\/p>\n<p><strong>TL;DR:<\/strong> environment variables (including <code>PATH<\/code>) and aliases work just the same in Zsh as they do in Bash, so if those are the only things you alter in your <code>~\/.bashrc<\/code>, then you can just copy it over to <code>~\/.zshrc<\/code>. But, if you alter Bash settings in your <code>~\/.bashrc<\/code>, you&#8217;ll need figure out the equivalent Zsh options and replace the relevant lines with the appropriate Zsh <code>setopt<\/code> or <code>unsetopt<\/code> Zsh commands.<\/p>\n<p><!--more--><\/p>\n<p style=\"font-style: italic;\"><strong style=\"color: red\">Note:<\/strong> The original version of this post wrongly asserted that Zsh avoided shell history duplication by default. This is not correct, and the post was updated with the details of how to update your <code>~\/.zshrc<\/code> file to avoid duplication of commands when you hit the up arrow in the shell.<\/p>\n<p>My <code>~\/.bashrc<\/code> file did just three things:<\/p>\n<ol>\n<li>Export environment variables<\/li>\n<li>Set command aliases<\/li>\n<li>Set non-default Bash Options<\/li>\n<\/ol>\n<h2>Environment Variables<\/h2>\n<p>As an example, my <code>~\/.bashrc<\/code> sets my SVN editor to <code>vi<\/code> by exporting an environment variable:<\/p>\n<pre class=\"lang:sh decode:true \" >\r\n# set the editor for SVN\r\nexport SVN_EDITOR=\/usr\/bin\/vi\r\n<\/pre>\n<p>Copying these lines un-changed to <code>~\/.zshrc<\/code> worked perfectly.<\/p>\n<h2>Command Aliases<\/h2>\n<p>As an example, my <code>~\/.bashrc<\/code> defines an alias to replace <code>ls<\/code> with <code>ls -GF<\/code> so I get colour-coded output when I list the contents of folders:<\/p>\n<pre class=\"lang:sh decode:true \" >\r\n# Get LS to work in colour\r\nalias ls=\"ls -GF\"\r\n<\/pre>\n<p>Again, copying these lines un-changed to <code>~\/.zshrc<\/code> worked perfectly.<\/p>\n<h2>Non-default Bash Options<\/h2>\n<p>On the whole I chose not to alter Bash&#8217;s default behaviour, but I did make one exception to that rule.<\/p>\n<p>On MacOs, when you enter the same command multiple times in a row in the same terminal window each copy of the command gets saved into the Bash history, so, when you hit the up arrow to get to previous commands, you have to hit up repeatedly to get to the command you entered before the one you repeated. I can&#8217;t comprehend why anyone would want this behaviour as the default, so, I changed it!<\/p>\n<p>Bash uses environment variables to control shell options, so, my <code>~\/.bashrc<\/code> contains the following lines to stop the duplication of repeated commands in the history:<\/p>\n<pre class=\"lang:sh decode:true \" >\r\n# stop bash saving duplicates to the history\r\nexport HISTCONTROL=ignoredups\r\n<\/pre>\n<p>Zsh doesn&#8217;t manage its optional settings via environment variables, it provides dedicated commands for that purpose \u00e2\u20ac\u201d <code>setopt<\/code> to set an option, and <code>unsetopt<\/code> to un-set an option.<\/p>\n<p>In general, you&#8217;ll need to find a matching Zsh option for each of your custom Bash options, and then add the appropriate <code>setopt<\/code> or <code>unsetopt<\/code> command into your <code>~\/.zshrc<\/code>.<\/p>\n<p>In this specific case, I needed to find the Zsh option that&#8217;s equivalent to <code>HISTCONTROL=ignoredups<\/code> in Bash.<\/p>\n<p>In both Bash and Zsh, when you hit the up arrow you are working your way through the shell&#8217;s history. Setting <code>HISTCONTROL=ignoredups<\/code> in Bash tells the shell not to add a command to the history if it&#8217;s the same as the previous command added to the history.<\/p>\n<p>The history file is not just used for the up arrow, it also serves as a record of the commands executed. By telling Bash to ignore duplicates that history is actually incomplete, so this is an imperfect solution. The problem is we are filtering the writes to the history, not the reads from the history.<\/p>\n<p>Zsh gives us much better options for controlling the history.<\/p>\n<p>If we want to filter what gets written to the history we can use the option <code>HIST_IGNORE_DUPS<\/code> to tell the shell not to store a command into the history if it&#8217;s a duplicate of the previously executed command. Or, we can be even more aggressive and use the <code>HIST_IGNORE_ALL_DUPS<\/code> option to tell the shell not to store a command into the history if it already exists anywhere within the entire history.<\/p>\n<p>A much better option IMO is Zsh&#8217;s <code>HIST_FIND_NO_DUPS<\/code> option. This does not filter what gets written to the history, but rather, what gets read back from the history when we do thinks like hit the up arrow. Do note that this filter does not just filter contiguous repeats, but repeats anywhere in in the history. This is how the <code>zshoptions<\/code> man page (man zshoptions) describes the option:<\/p>\n<blockquote><p>\n<code>HIST_FIND_NO_DUPS:<\/code> When searching for history entries in the line editor, do not display duplicates of a line previously found, even if the duplicates are not contiguous.\n<\/p><\/blockquote>\n<p><del datetime=\"2019-09-26T00:29:14+00:00\">I decided that of the three options, <code>HIST_FIND_NO_DUPS<\/code> made the most sense for me, so I added the following to my <code>~\/.zshrc<\/code> file:<\/p>\n<pre class=\"lang:zsh decode:true \" >\r\n# prevent duplicates when hitting the up arrow in the shell\r\nsetopt HIST_FIND_NO_DUPS\r\n<\/pre>\n<p><\/del><\/p>\n<p><ins datetime=\"2019-09-26T00:29:14+00:00\"><strong>Update \u00e2\u20ac\u201d 26 September 2019<\/strong>: <code>HIST_FIND_NO_DUPS:<\/code> is not working for me on MacOS Mojave, so switched to <code>HIST_IGNORE_DUPS:<\/code>:<\/p>\n<pre class=\"lang:zsh decode:true \" >\r\n# prevent duplicates when hitting the up arrow in the shell\r\nsetopt HIST_IGNORE_DUPS\r\n<\/pre>\n<p><\/ins><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"pps-series-post-details pps-series-post-details-variant-classic pps-series-post-details-18702 pps-series-meta-excerpt\" data-series-id=\"581\"><div class=\"pps-series-meta-content\"><div class=\"pps-series-meta-text\">This entry is part 6 of 6 in the series <a href=\"https:\/\/www.bartbusschots.ie\/s\/series\/bash-to-zsh\/\">Bash to Zsh<\/a><\/div><\/div><\/div><p>Having used Zsh rather than Bash for over a week it was time to make the move permanent by migrating my shell customisations from ~\/.bashrc to ~\/.zshrc. Your milage may vary, but I was pleased to find I didn&#8217;t need to make any changes, and, that I could get rid of one command from the [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[12,446],"tags":[414,406,458,580],"series":[581],"class_list":["post-15905","post","type-post","status-publish","format-standard","hentry","category-computers-tech","category-sysadmin","tag-bash","tag-commandline","tag-tutorial","tag-zsh","series-bash-to-zsh"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p7t9xK-48x","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/posts\/15905","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/comments?post=15905"}],"version-history":[{"count":5,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/posts\/15905\/revisions"}],"predecessor-version":[{"id":16017,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/posts\/15905\/revisions\/16017"}],"wp:attachment":[{"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/media?parent=15905"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/categories?post=15905"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/tags?post=15905"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/www.bartbusschots.ie\/s\/wp-json\/wp\/v2\/series?post=15905"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}