{"id":521,"date":"2011-06-04T21:09:48","date_gmt":"2011-06-05T02:09:48","guid":{"rendered":"http:\/\/www.triatlantico.org\/blog\/?p=521"},"modified":"2021-11-20T19:07:44","modified_gmt":"2021-11-21T00:07:44","slug":"useful-bash-functions","status":"publish","type":"post","link":"https:\/\/www.triatlantico.org\/blog\/2011\/06\/04\/useful-bash-functions","title":{"rendered":"Useful bash functions|Fun\u00e7\u00f5es \u00fateis em bash"},"content":{"rendered":"<p>[lang_en]If you, like me, strive to keep a well organized and modular configuration setup, sooner or later will split your bash configuration into multiple files. And if you want it to be valid for multiple machines you&#8217;ll appreciate the following function:[\/lang_en][lang_pt]Se, como eu, sempre tenta organizar e ter uma configura\u00e7\u00e3o modular, mais cedo ou mais tarde vai separar a configura\u00e7\u00e3o bash em v\u00e1rios ficheiros. Al\u00e9m disso, se quiser usar a mesma em v\u00e1rias m\u00e1quinas, esta fun\u00e7\u00e3o d\u00e1 jeito:[\/lang_pt]<\/p>\n<pre>\n\n<div class=\"codecolorer-container bash vibrant\" style=\"overflow:auto;white-space:nowrap;width:480px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/><\/div><\/td><td><div class=\"bash codecolorer\">source_if_exists <span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">for<\/span> i_; <span class=\"kw1\">do<\/span> <span class=\"kw3\">test<\/span> <span class=\"re5\">-f<\/span> <span class=\"st0\">&quot;<span class=\"es2\">$i_<\/span>&quot;<\/span> <span class=\"sy0\">&amp;&amp;<\/span> <span class=\"kw3\">source<\/span> <span class=\"st0\">&quot;<span class=\"es2\">$i_<\/span>&quot;<\/span>; <span class=\"kw1\">done<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n<\/pre>\n<p>[lang_en]This way, you can try to process other configuration fragments only when they exist:[\/lang_en][lang_pt]Desta forma pode tentar incluir os fragmentos apenas onde e quando existem:[\/lang_pt]<\/p>\n<pre>\n\n<div class=\"codecolorer-container bash vibrant\" style=\"overflow:auto;white-space:nowrap;width:480px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/><\/div><\/td><td><div class=\"bash codecolorer\">source_if_exists <span class=\"co1\">${HOME}<\/span><span class=\"sy0\">\/<\/span>etc<span class=\"sy0\">\/<\/span>bash_completion<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n<\/pre>\n<p>[lang_en]Another common need for bash configuration is to either append or prepend paths to an environment variable. When doing a configuration for multiple machines it is always a pain to make sure those paths exist. These functions take care of that making adding directories to the path a breeze:[\/lang_en][lang_pt]Algo que tamb\u00e9m \u00e9 comum fazer \u00e9 acrescentar um direct\u00f3rio a uma vari\u00e1vel de ambiente. Quando se faz uma configura\u00e7\u00e3o para v\u00e1rias m\u00e1quina \u00e9 sempre um inconveniente assegurar que os direct\u00f3rios existem. Estas fun\u00e7\u00f5es tratam do problema:[\/lang_pt]<\/p>\n<pre>\n\n<div class=\"codecolorer-container bash vibrant\" style=\"overflow:auto;white-space:nowrap;width:480px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/><\/div><\/td><td><div class=\"bash codecolorer\">safe_prepend_path<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"re2\">VAR<\/span>=<span class=\"re4\">$1<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw3\">shift<\/span><br \/>\n&nbsp; &nbsp; <span class=\"re2\">VAL<\/span>=$<span class=\"br0\">&#40;<\/span><span class=\"kw3\">eval<\/span> <span class=\"kw3\">echo<\/span> \\$<span class=\"co1\">${VAR}<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">for<\/span> i_; <span class=\"kw1\">do<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">test<\/span> <span class=\"re5\">-d<\/span> <span class=\"st0\">&quot;<span class=\"es2\">$i_<\/span>&quot;<\/span> <span class=\"sy0\">&amp;&amp;<\/span> <span class=\"re2\">VAL<\/span>=<span class=\"re1\">$i_<\/span><span class=\"co1\">${VAL:+&quot;:$VAL&quot;}<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">done<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw3\">eval<\/span> <span class=\"kw3\">export<\/span> <span class=\"co1\">${VAR}<\/span>=$<span class=\"br0\">&#40;<\/span><span class=\"kw3\">echo<\/span> <span class=\"co1\">${VAL}<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><br \/>\n<br \/>\nsafe_append_path<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"re2\">VAR<\/span>=<span class=\"re4\">$1<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw3\">shift<\/span><br \/>\n&nbsp; &nbsp; <span class=\"re2\">VAL<\/span>=$<span class=\"br0\">&#40;<\/span><span class=\"kw3\">eval<\/span> <span class=\"kw3\">echo<\/span> \\$<span class=\"co1\">${VAR}<\/span><span class=\"br0\">&#41;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">for<\/span> i_; <span class=\"kw1\">do<\/span><br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw3\">test<\/span> <span class=\"re5\">-d<\/span> <span class=\"st0\">&quot;<span class=\"es2\">$i_<\/span>&quot;<\/span> <span class=\"sy0\">&amp;&amp;<\/span> <span class=\"re2\">VAL<\/span>=<span class=\"co1\">${VAL:+&quot;$VAL:&quot;}<\/span><span class=\"re1\">$i_<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw1\">done<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw3\">eval<\/span> <span class=\"kw3\">export<\/span> <span class=\"co1\">${VAR}<\/span>=$<span class=\"br0\">&#40;<\/span><span class=\"kw3\">echo<\/span> <span class=\"co1\">${VAL}<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n<\/pre>\n<p>[lang_en]Example:[\/lang_en][lang_pt]Exemplos:[\/lang_pt]<\/p>\n<pre>\n\n<div class=\"codecolorer-container bash vibrant\" style=\"overflow:auto;white-space:nowrap;width:480px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/><\/div><\/td><td><div class=\"bash codecolorer\">safe_prepend_path PATH <span class=\"sy0\">\/<\/span>opt<span class=\"sy0\">\/<\/span>local<span class=\"sy0\">\/<\/span>bin <span class=\"co1\">${HOME}<\/span><span class=\"sy0\">\/<\/span>bin<br \/>\nsafe_append_path MANPATH <span class=\"sy0\">\/<\/span>opt<span class=\"sy0\">\/<\/span>local<span class=\"sy0\">\/<\/span><span class=\"kw2\">man<\/span> <span class=\"co1\">${HOME}<\/span><span class=\"sy0\">\/<\/span><span class=\"kw2\">man<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n<\/pre>\n<p>[lang_en]Also, it is not unusual to have some path variables with duplicate entries, which is not very efficient. This function makes sure that a path only occurs once, and retains only the first occurrence, thus keeping the search order intact.[\/lang_en][lang_pt]\u00c9 frequente que as vari\u00e1veis de ambiente com direct\u00f3rios apresentem entradas duplicadas o que torna a pesquisa menos eficiente. Esta fun\u00e7\u00e3o assegura que cada direct\u00f3rio ocorre apenas uma vez e retem apenas a primeira entrada, mantendo por isso a ordem.[\/lang_pt]<\/p>\n<pre>\n\n<div class=\"codecolorer-container bash vibrant\" style=\"overflow:auto;white-space:nowrap;width:480px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/><\/div><\/td><td><div class=\"bash codecolorer\">unique_path<span class=\"br0\">&#40;<\/span><span class=\"br0\">&#41;<\/span> <span class=\"br0\">&#123;<\/span><br \/>\n&nbsp; &nbsp; <span class=\"kw3\">eval<\/span> <span class=\"kw3\">export<\/span> <span class=\"re4\">$1<\/span>=$<span class=\"br0\">&#40;<\/span><span class=\"kw3\">echo<\/span> $<span class=\"br0\">&#40;<\/span><span class=\"kw3\">eval<\/span> <span class=\"kw3\">echo<\/span> \\$<span class=\"co1\">${1}<\/span><span class=\"br0\">&#41;<\/span> <span class=\"sy0\">|<\/span> \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"kw2\">awk<\/span> -F: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; <span class=\"st_h\">'{ a[$1]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf &quot;%s&quot;,$1; &nbsp; &nbsp; &nbsp; &nbsp;\\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;for(i=2;i&lt;=NF;i++) { &nbsp; \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(!($i in a)) { &nbsp; &nbsp; \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf &quot;:%s&quot;,$i; &nbsp; \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a[$i]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;printf &quot;\\n&quot;; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \\<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}'<\/span><span class=\"br0\">&#41;<\/span><br \/>\n<span class=\"br0\">&#125;<\/span><\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n<\/pre>\n<p>[lang_en]Example:[\/lang_en][lang_pt]Examples:[\/lang_pt]<\/p>\n<pre>\n\n<div class=\"codecolorer-container bash vibrant\" style=\"overflow:auto;white-space:nowrap;width:480px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/><\/div><\/td><td><div class=\"bash codecolorer\">unique_path PATH<br \/>\nunique_path MANPATH<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>[lang_en]If you, like me, strive to keep a well organized and modular configuration setup, sooner or later will split your bash configuration into multiple files. And if you want it to be valid for multiple machines you&#8217;ll appreciate the following function:[\/lang_en][lang_pt]Se, como eu, sempre tenta organizar e ter uma configura\u00e7\u00e3o modular, mais cedo ou mais [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,62],"tags":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pmzAM-8p","_links":{"self":[{"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/posts\/521"}],"collection":[{"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/comments?post=521"}],"version-history":[{"count":31,"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/posts\/521\/revisions"}],"predecessor-version":[{"id":1767,"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/posts\/521\/revisions\/1767"}],"wp:attachment":[{"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/media?parent=521"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/categories?post=521"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.triatlantico.org\/blog\/wp-json\/wp\/v2\/tags?post=521"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}