<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7389078</id><updated>2026-07-01T22:19:40.183+08:00</updated><category term="google"/><category term="productivity"/><category term="Git"/><category term="GMail"/><category term="OSX"/><category term="Google Apps"/><category term="Software engineering"/><category term="Python"/><category term="Blogger"/><category term="Chrome"/><category term="Facebook"/><category term="Google Chrome"/><category term="Google Sites"/><category term="Linux"/><category term="OS X"/><category term="Security"/><category term="google+"/><category term="windows"/><category term="Twitter"/><category term="email"/><category term="troubleshooting"/><category term="Android"/><category term="Firefox"/><category term="Gitbucket"/><category term="Malaysia"/><category term="Quora"/><category term="Shell"/><category term="bash"/><category term="career"/><category term="google docs"/><category term="vscode"/><category term="About.me"/><category term="CSS"/><category term="Google Calendar"/><category term="Google Tasks"/><category term="Homebrew"/><category term="ImageMagick"/><category term="Java"/><category term="LinkedIn"/><category term="Scala"/><category term="Search Engines"/><category term="SourceTree"/><category term="Startup"/><category term="gMalaysia"/><category term="github"/><category term="goo.gl"/><category term="google drive"/><category term="microsoft"/><category term="php"/><category term="powerpoint"/><category term="privacy"/><category term="social network"/><category term="yarn"/><category term="AOL"/><category term="ASP.NET"/><category term="Address book"/><category term="Answer Engines"/><category term="Bug tracking system"/><category term="Business card"/><category term="DBA"/><category term="Database administrator"/><category term="Domain name"/><category term="Email Thread"/><category term="Email address"/><category term="Excel"/><category term="Flask"/><category term="Font"/><category term="Frommers"/><category term="G42"/><category term="GMBO"/><category term="Gender Inequality"/><category term="Google Calender"/><category term="Google Contacts"/><category term="Google Maps"/><category term="Google Site"/><category term="Google Spreadsheets"/><category term="Google Talk"/><category term="Google Translate"/><category term="Google search"/><category term="Google+ Communities"/><category term="Hack"/><category term="IME"/><category term="IntelliJ"/><category term="Jobs"/><category term="Kerberos"/><category term="Lonely Planet"/><category term="MDEC"/><category term="Microsoft Outlook"/><category term="Mozilla Firefox"/><category term="MozillaZine"/><category term="NTFS"/><category term="NTLM"/><category term="Oppression and Intolerance"/><category term="Oracle"/><category term="PDF"/><category term="Performance"/><category term="Pycon"/><category term="QR"/><category term="QR Code"/><category term="R"/><category term="Reactive"/><category term="Recreation"/><category term="Reviews"/><category term="Rolodex"/><category term="SSH"/><category term="Search"/><category term="Short URL"/><category term="Slavery"/><category term="Spreadsheets"/><category term="TCM"/><category term="Travel"/><category term="Travel literature"/><category term="TripWolf"/><category term="URL shortener"/><category term="Unified Communications"/><category term="Web Designer"/><category term="Web development"/><category term="Wi-Fi"/><category term="Windows Server 2008"/><category term="Wireless network"/><category term="Wolfram"/><category term="Workflow"/><category term="agile"/><category term="annoyances"/><category term="architecture"/><category term="attachment"/><category term="audio"/><category term="azure"/><category term="bandwidth"/><category term="books"/><category term="browser"/><category term="burton"/><category term="china"/><category term="cmder"/><category term="codec"/><category term="comic"/><category term="comparison"/><category term="composer"/><category term="cpu"/><category term="curl"/><category term="data science"/><category term="data visualization"/><category term="designer"/><category term="developers"/><category term="devfest"/><category term="discount code"/><category term="docker"/><category term="ebooks"/><category term="ecommerce"/><category term="emulator"/><category term="entrepreneurship"/><category term="family life"/><category term="ffmpeg"/><category term="freelance"/><category term="freelancing"/><category term="funny"/><category term="getmybusinessonline"/><category term="ghostscript"/><category term="gif"/><category term="golang"/><category term="google plus"/><category term="hardware"/><category term="html5"/><category term="humour"/><category term="ifttt"/><category term="internet_explorer"/><category term="it_framework"/><category term="javascript"/><category term="kernel"/><category term="knowledge graph"/><category term="law"/><category term="localization"/><category term="macos"/><category term="management"/><category term="mashups"/><category term="microsoft office"/><category term="movies"/><category term="ms_office"/><category term="node"/><category term="office live"/><category term="open source"/><category term="opus"/><category term="password"/><category term="platform"/><category term="problem solving"/><category term="proxy"/><category term="pytest"/><category term="qigong"/><category term="regex"/><category term="research"/><category term="self-development"/><category term="solutions"/><category term="standards"/><category term="torture"/><category term="video"/><category term="video transcoding"/><category term="vue.js"/><category term="vuepress"/><category term="web hosting"/><category term="webm"/><category term="website"/><category term="windows azure"/><category term="word cloud"/><category term="wordpress"/><title type='text'>Hanxue and IT</title><subtitle type='html'>Software engineering lessons learned from the trenches. Mixture of software engineering methods, git and various programming languages. </subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>177</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7389078.post-8111491654251640626</id><published>2025-03-21T22:21:00.002+08:00</published><updated>2025-03-21T23:35:33.058+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="qigong"/><category scheme="http://www.blogger.com/atom/ns#" term="research"/><category scheme="http://www.blogger.com/atom/ns#" term="TCM"/><title type='text'>TCM Qigong Research Areas</title><content type='html'>&lt;p&gt;&amp;nbsp;TCM Traditional Qigong is linked with other research/scientific areas&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Physiology and Metabolism Research&lt;/h2&gt;&lt;p&gt;Focal Point: Impact of Qigong on Autonomic Nervous System as well as metabolic indicators.&lt;/p&gt;&lt;p&gt;Research Examples:&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&amp;nbsp;2021 research published in Frontiers of Physiology shows that long term Taijiquan practice reduces sympathetic (nervous system) activity, increasing parasympathetic nervous activities (heart rate variability, HRV), reducing metabolic syndromes resulting from chronic stress (e.g. insulin resistance)&lt;/li&gt;&lt;li&gt;&amp;nbsp;Research technique: combine wearable devices (e.g. Empatica E4) for real-time heart rate and galvanic skin response (electric conductivity)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Neural Plasticity and Brain Function&lt;/h2&gt;&lt;p&gt;&amp;nbsp;Research Breakthrough: How qigong affect&#39;s the brain&#39;s Default Mode Network (DMN)&lt;/p&gt;&lt;p&gt;Research Examples:&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;In 2022, Beijing University uses fMRI proves that Baduanjin practitioners show increased functional connectivity during the brain&#39;s resting state, prefrontal cortex increases limbic system coordination. These are related to emotional regulation functions.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Technology used: Deep Learning MRI&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Immune System Regulation and Epigenetics&lt;/h2&gt;&lt;p&gt;New development: Qigong&#39;s impact on immune cell epigenesis (e.g. DNA methylation)&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;America&#39;s NIH&amp;nbsp;research  grant NCT03925311 shows that after 6 months of Qigong practice by breast cancer patients, CD4+ T cell&#39;s FOXP3 gene methylation level significantly reduced, resulting in immunosuppresion relief.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Methodology: Whole Gene Bisulfite Sequencing (WGBS) combined flow cytometry&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Relationship between Biological Science and Energy Medicine&lt;/h2&gt;&lt;p&gt;Controversy and Exploration: Exploring the physical aspects of Qigong&#39;s &quot;External Qi&quot;&lt;/p&gt;&lt;p&gt;Research Cases&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&amp;nbsp;Shanghai Jiao Tong University research team using SQUID (Superconducting quantum interference) probing a Qigong master releasing Qi showing that there is an increase of low-frequency electromagnetic field (0.1-30Hz) by 10-100 times compared to a regular person. The frequency characteristics is similar to physiological rhythm.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Challenge: need to exclude environmental interference (for example: geomagnetic interference), there is some dispute on research reproductibility&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/8111491654251640626/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/8111491654251640626' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/8111491654251640626'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/8111491654251640626'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2025/03/tcm-qigong-research-areas.html' title='TCM Qigong Research Areas'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-6527995720338537634</id><published>2025-02-27T20:57:00.001+08:00</published><updated>2025-02-27T20:59:31.862+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="powerpoint"/><category scheme="http://www.blogger.com/atom/ns#" term="productivity"/><title type='text'>How to quickly extract all photos at the original quality from powerpoint slides</title><content type='html'>&lt;p&gt;&amp;nbsp;I want to extract a lot of useful imaging photos from a Powerpoint slide deck, and the usual way to select each photo and save them has two distinct disadvantages:&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;time consuming and repetitive&lt;/li&gt;&lt;li&gt;photos are not saved as the original quality&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Modern Powerpoint files with the .pptx extension are actually zip archives. Rename the .pptx file into .zip file, and look into the media folder.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&amp;nbsp;&lt;/p&gt;&lt;p&gt;If it&#39;s an older .ppt Powerpoint file, first open up the file in Powerpoint, then save as .pptx&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVaQCELE_F6ByAZAwkANSo5iOla0djHKflXgFEtiJ7Aqsin6dJz6QI0yNApN5IjFZz54VTIspbXUNGyIIfdJVomowSdAb91qkvgby-SwjUzuUo7tQO9hX7ff20gmF5-7YscB1p16qYMu-xXKS2W3047UFmqStXSbn3-I_jvboIvmlxfyUik_fV/s271/Screenshot%202025-02-27%20204043.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;240&quot; data-original-width=&quot;271&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVaQCELE_F6ByAZAwkANSo5iOla0djHKflXgFEtiJ7Aqsin6dJz6QI0yNApN5IjFZz54VTIspbXUNGyIIfdJVomowSdAb91qkvgby-SwjUzuUo7tQO9hX7ff20gmF5-7YscB1p16qYMu-xXKS2W3047UFmqStXSbn3-I_jvboIvmlxfyUik_fV/s16000/Screenshot%202025-02-27%20204043.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Using Windows Explorer, browse to the location of the Powerpoint file, and rename the .pptx file to .zip&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOLM4qwgslTOsT_2tmIZN0EpixEKvs905hZyzSvA-Pa-cdR7jNreliyf2qNuQvt-Nw-zjeVoLfr9FrB0l2QQVLTg2o4dCEfREdaQ0YPDNojm-vCwDO1ORUZnbAqR5vwqGWfVaGvSGz1leOPxHJbB7Hvh600O3Eo-ugADVAeYlZSP2v9KD4E-f_/s705/Screenshot%202025-02-27%20205158.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;81&quot; data-original-width=&quot;705&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOLM4qwgslTOsT_2tmIZN0EpixEKvs905hZyzSvA-Pa-cdR7jNreliyf2qNuQvt-Nw-zjeVoLfr9FrB0l2QQVLTg2o4dCEfREdaQ0YPDNojm-vCwDO1ORUZnbAqR5vwqGWfVaGvSGz1leOPxHJbB7Hvh600O3Eo-ugADVAeYlZSP2v9KD4E-f_/s16000/Screenshot%202025-02-27%20205158.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;Using Windows Explorer or a File archiver utility such as PeaZip, extract the content of the newly named .zip file&lt;/p&gt;&lt;p&gt;&amp;nbsp; You should now see a &lt;b&gt;ppt&lt;/b&gt; folder, with a media &lt;b&gt;subfolder&lt;/b&gt; containing all the photos in the slides.&amp;nbsp;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0cXgfyh2vUcvnzbKdfcfUVTy205KXo7qxop5vtlapmIpSPb7Nuk0GvPXW8WR2cWmqjLFjhwSbLPfZoUDn8pGCl6KtRTRFJtawG_9-gnohVsA-zzlPJ-U0-bbyG8j45s1Z9n7Fh8mMz2w9qcOTxW7lC0cyYm_IDfDZhIRgX0whCtKl-zYck3Yo/s1200/Screenshot%202025-02-27%20205605.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;313&quot; data-original-width=&quot;1200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0cXgfyh2vUcvnzbKdfcfUVTy205KXo7qxop5vtlapmIpSPb7Nuk0GvPXW8WR2cWmqjLFjhwSbLPfZoUDn8pGCl6KtRTRFJtawG_9-gnohVsA-zzlPJ-U0-bbyG8j45s1Z9n7Fh8mMz2w9qcOTxW7lC0cyYm_IDfDZhIRgX0whCtKl-zYck3Yo/s16000/Screenshot%202025-02-27%20205605.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/6527995720338537634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/6527995720338537634' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/6527995720338537634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/6527995720338537634'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2025/02/how-to-quickly-extract-all-photos-from-powerpoint-slides.html' title='How to quickly extract all photos at the original quality from powerpoint slides'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVaQCELE_F6ByAZAwkANSo5iOla0djHKflXgFEtiJ7Aqsin6dJz6QI0yNApN5IjFZz54VTIspbXUNGyIIfdJVomowSdAb91qkvgby-SwjUzuUo7tQO9hX7ff20gmF5-7YscB1p16qYMu-xXKS2W3047UFmqStXSbn3-I_jvboIvmlxfyUik_fV/s72-c/Screenshot%202025-02-27%20204043.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>China, Shang Hai Shi, Xu Hui Qu, 零陵路530号 邮政编码: 200032</georss:featurename><georss:point>31.189043 121.450955</georss:point><georss:box>2.8788091638211561 86.294705 59.499276836178851 156.607205</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-6415051905074092378</id><published>2019-09-24T23:23:00.002+08:00</published><updated>2019-09-25T01:25:55.652+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="career"/><category scheme="http://www.blogger.com/atom/ns#" term="self-development"/><title type='text'>Resignation Letter - May 2020</title><content type='html'>&lt;blockquote class=&quot;tr_bq&quot;&gt;
Dear Manager,&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I hereby tender my resignation for OrgX effective on 17th May 2020.&lt;br /&gt;
&lt;br /&gt;
It has been my great pleasure to serve in OrgX for a year. Since day 1, I realized that OrgX is different from other companies. This is a product-focused organization that values engineering, rather than trying to please Wall Street at all cost every quarter. There is great camaraderie and belief that we will continue to lead the industry.&lt;br /&gt;
&lt;br /&gt;
However, when I look back at my own contribution to OrgX and to the tech industry at the whole, I realize that I have failed to make any positive contributions. Whilst I am a valued team member and perform well according to our KPI, I have not been able to make any significant contribution to increase our effectiveness and productivity by pushing the boundary of what is possible.&lt;br /&gt;
&lt;br /&gt;
In short, I have become a cog in the wheel treating symptoms rather than using my ability to think and solve problems faced both by OrgX and others in my industry.&lt;br /&gt;
&lt;br /&gt;
To carry on means I am settling. That &lt;a href=&quot;https://stratechery.com/2019/day-two-to-one-day/&quot;&gt;I am in Day Two&lt;/a&gt;. I am no longer the highly motivated engineer who wants to create the best products for the world, I no longer care about taking away friction in my colleagues&#39; day-to-day work. I no longer dare to crest the next wave and clamber the next mountain, and would rather cross my arms and look back in satisfaction.&lt;br /&gt;
&lt;br /&gt;
A Ship in Harbor Is Safe, But that Is Not What Ships Are Built For.&lt;br /&gt;
&lt;br /&gt;
I sincerely hope that whomever is replacing my role will have the vision and drive to bring OrgX to greater heights.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Best regards,&lt;br /&gt;
Lee Hanxue&lt;/blockquote&gt;
&lt;br /&gt;
I write this resignation letter not because I plan to quit from my current organization in one year&#39;s time. Neither am I writing this letter to get some negotiating leverage. I write it because a couple of years ago, I realized that life is finite. Anything broken can be fixed, but time wasted cannot be regained. I have never heard of anyone on their death bed regretting not doubling their net worth. But I have always heard of regrets of not taking the shot, giving up their childhood or lifelong dreams, not being kinder, not spending more time with their loved ones.&lt;br /&gt;
&lt;br /&gt;
I do not want to work just to pay bills, or to keep up with the Jones-es. There are many options in life to pay bills, to feed the family and so on. And I do not want to squander the limited time I have to please my bosses and wait for my monthly paychecks.&lt;br /&gt;
&lt;br /&gt;
Even if I fail, I would have the satisfaction of putting all my heart and soul to solve problems in my industry, and make the world just that little bit better.&lt;br /&gt;
&lt;br /&gt;
These do not need to be novel creations but could be as mundane as:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;shortening the product life-cycle by 30%&lt;/li&gt;
&lt;li&gt;implementing a continuous delivery pipeline for AI inferencing solutions&lt;/li&gt;
&lt;li&gt;preventing certain types of failures from occurring&lt;/li&gt;
&lt;li&gt;creating a higher level of abstraction for engineering teams, resulting in &amp;gt;10% increase in productivity&lt;/li&gt;
&lt;li&gt;implementing AI inferencing framework at hardware level (e.g. Tensorflow on FPGA)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tensorflow.org/tfx&quot;&gt;implementing TFX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;higher AI workflow utilization (e.g. &lt;a href=&quot;https://slurm.schedmd.com/documentation.html&quot;&gt;slurm&lt;/a&gt;) &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
I had the opportunity to work in one of the best company in the world. My regret was not about quitting my job, but not quitting early because as good as the company was overall, business changes means there are no longer opportunities for me to push the boundary of technology to increase more business value. I do not wish to repeat the same mistake twice. </content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/6415051905074092378/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/6415051905074092378' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/6415051905074092378'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/6415051905074092378'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/09/resignation-letter-may-2020.html' title='Resignation Letter - May 2020'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total><georss:featurename>Nan Luo Gu Xiang, Dongcheng Qu, Beijing Shi, China</georss:featurename><georss:point>39.9371015 116.40315169999997</georss:point><georss:box>39.9249265 116.38298169999997 39.949276499999996 116.42332169999996</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-2926683319639511439</id><published>2019-08-12T12:53:00.001+08:00</published><updated>2019-08-12T13:18:57.896+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="proxy"/><title type='text'>Comprehensive Guide for proxy settings for Chrome</title><content type='html'>If you work in a large enterprise or use chrome in a school, chances are Google Chrome access the Internet through a proxy server.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhed9tI7oS4YzNGwRx7EacET82NifFAqq816XiS0yKBc_vW1OswfqS4DjvoEGsi2fJzqPiJNoM9y87SCtOuzTxzmG9ZGGlWyUSOhpJOchVZ8Vs2Xg66e0EQNtGoGwDYu9dFD2rGKQ/s1600/browser_with_proxy.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;300&quot; data-original-width=&quot;650&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhed9tI7oS4YzNGwRx7EacET82NifFAqq816XiS0yKBc_vW1OswfqS4DjvoEGsi2fJzqPiJNoM9y87SCtOuzTxzmG9ZGGlWyUSOhpJOchVZ8Vs2Xg66e0EQNtGoGwDYu9dFD2rGKQ/s1600/browser_with_proxy.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
What is a proxy server? It is simply &lt;a href=&quot;https://en.wikipedia.org/wiki/Proxy_server&quot;&gt;an intermediary between two machines that want to communicate with each other&lt;/a&gt;: Google Chrome on your laptop and the web server hosting websites on the Internet. The more important question is, why use a proxy server? Some of the reasons are:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Security: only safe websites are allowed and unsafe or inappropriate websites are blocked&lt;/li&gt;
&lt;li&gt;Limit access: only devices that are allowed to have Internet access can connect to the proxy server&lt;/li&gt;
&lt;li&gt;Accountability: know who is accessing what resources&lt;/li&gt;
&lt;li&gt;Speed: proxy servers used in conjunction with caching server can speed up access&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;h3&gt;
Chrome Proxy Settings&lt;/h3&gt;
Once upon a time, setting proxy server settings is straightforward. For example, in Internet explorer, go to &lt;b&gt;Internet Options&lt;/b&gt; and insert the proxy address.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3aJd8ExI9-ftlpXmPiYvB245Fo0gWzyKUSJEptocUFNdSy9SJsR7tNx9FgSINDuZZJYk8b2RuTiniOrq7TINROLEkNJWpJLwst6Y16T7ioj_SqHmlCUjr7bEixMEUqPNd01sRWQ/s1600/2019-08-12_Internet_Options_Proxy.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;526&quot; data-original-width=&quot;776&quot; height=&quot;433&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3aJd8ExI9-ftlpXmPiYvB245Fo0gWzyKUSJEptocUFNdSy9SJsR7tNx9FgSINDuZZJYk8b2RuTiniOrq7TINROLEkNJWpJLwst6Y16T7ioj_SqHmlCUjr7bEixMEUqPNd01sRWQ/s640/2019-08-12_Internet_Options_Proxy.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
This used to be the case for Chrome, until it changed to using the Operating Systems&#39; proxy settings&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqWlp_Fht4nYdbKdddojXtp8yvUjyyqLwX4km0-FLClCoYngy4FRCl2D6ADgKcFTdEkz8G5rmlzLkvVCGpZMwKUW5uHG-JEsXVKReIInDFXnyQnJBcf8K10ecWNRVHOEczfhvPtg/s1600/2019-08-11_Chrome_Proxy_Settings.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;627&quot; data-original-width=&quot;1600&quot; height=&quot;156&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqWlp_Fht4nYdbKdddojXtp8yvUjyyqLwX4km0-FLClCoYngy4FRCl2D6ADgKcFTdEkz8G5rmlzLkvVCGpZMwKUW5uHG-JEsXVKReIInDFXnyQnJBcf8K10ecWNRVHOEczfhvPtg/s400/2019-08-11_Chrome_Proxy_Settings.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
So Chrome does not automatically set the proxy, but you use your Operating System&#39;s proxy settings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Windows Proxy Settings&lt;/h3&gt;
Windows 10 has a new proxy Settings. &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQMBGJW-zuqGwBewNCqQPzcdrZZbkD1SdB7-sdM-irTC5fJZtD_vLmmndH0FPHtulYnVbbmp1uG4V9elxNnB5c0OPSd4oEsiwBwL-IZ9H7Ofmv2DT7460HtS-xiO9MBcfVlkkzaQ/s1600/2019-08-11_Windows_Socks_Proxy_Settings_with_Exclusions.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;483&quot; data-original-width=&quot;491&quot; height=&quot;314&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQMBGJW-zuqGwBewNCqQPzcdrZZbkD1SdB7-sdM-irTC5fJZtD_vLmmndH0FPHtulYnVbbmp1uG4V9elxNnB5c0OPSd4oEsiwBwL-IZ9H7Ofmv2DT7460HtS-xiO9MBcfVlkkzaQ/s320/2019-08-11_Windows_Socks_Proxy_Settings_with_Exclusions.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
But the legacy Internet Options settings is still valid - check that nothing is set there.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN-8kI2uFHiJ78-oc0J2GvdOnWL2N3XUXYuZHCingcOkGRNkuZFk1vJ4sSztd0omAna9s-MBe0XZp4aZmT2cx32L83jbWamxchI8i4WpZr8yeSbUhOEY3y0lIb4lZ1AvQu2HidXA/s1600/2019-08-11+21_32_14-Configuring+socks+5+proxy+in+window+10+.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;367&quot; data-original-width=&quot;372&quot; height=&quot;315&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN-8kI2uFHiJ78-oc0J2GvdOnWL2N3XUXYuZHCingcOkGRNkuZFk1vJ4sSztd0omAna9s-MBe0XZp4aZmT2cx32L83jbWamxchI8i4WpZr8yeSbUhOEY3y0lIb4lZ1AvQu2HidXA/s320/2019-08-11+21_32_14-Configuring+socks+5+proxy+in+window+10+.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Windows also reads the &lt;kbd&gt;HTTP_PROXY&lt;/kbd&gt; and &lt;kbd&gt;HTTPS_PROXY&lt;/kbd&gt; environment variable. If you find that you have no proxy settings enabled but Chrome is still acting weird, check for these environment variables.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4mywsrQbAK6tMt8JFvWMJHa3MMckoN1m_AhDL71myhREC6BLLVYIiQAamXyfy7mFRlQS524ggUX60IrRRrAUOnquKnzVbzjHr11caKriK_-LPeBX_mWfcUQzzYZXUJKt_5M6fpQ/s1600/WIndows_Environment-Variables-Proxy.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1240&quot; data-original-width=&quot;1148&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4mywsrQbAK6tMt8JFvWMJHa3MMckoN1m_AhDL71myhREC6BLLVYIiQAamXyfy7mFRlQS524ggUX60IrRRrAUOnquKnzVbzjHr11caKriK_-LPeBX_mWfcUQzzYZXUJKt_5M6fpQ/s320/WIndows_Environment-Variables-Proxy.png&quot; width=&quot;296&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
macOS Proxy Settings&lt;/h3&gt;
You can set proxy server details in System Preferences&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6XIFnBjstiVa-1M_1rftEn5vBuP2MyrUVbeKpYY1MiPS1scr9yjgRZTskMsFgD79QCAzwvifh9Xh4ZxkGUGq0NAorMCA6MawrCilnvjFycLvu26eY_mkLRE6uf0FgHHqyuMpQ9g/s1600/macos-http-proxy-settings-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;577&quot; data-original-width=&quot;666&quot; height=&quot;346&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6XIFnBjstiVa-1M_1rftEn5vBuP2MyrUVbeKpYY1MiPS1scr9yjgRZTskMsFgD79QCAzwvifh9Xh4ZxkGUGq0NAorMCA6MawrCilnvjFycLvu26eY_mkLRE6uf0FgHHqyuMpQ9g/s400/macos-http-proxy-settings-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
You can set the proxy settings from command line too&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
networksetup -setwebproxy &quot;Wi-fi&quot; 127.0.0.1 8080
networksetup -setwebproxystate &quot;Wi-fi&quot; on
networksetup -getwebproxy &quot;Wi-Fi&quot;



&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
And for SOCKS proxy&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
networksetup -setsocksfirewallproxy wi-fi localhost 1080
networksetup -setsocksfirewallproxystate &quot;Wi-Fi&quot; on
networksetup -getsocksfirewallproxystate &quot;Wi-Fi&quot;


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Linux Proxy Settings&lt;/h3&gt;
The best way to set proxy is to use environment variables, so that the settings is applied to all applications, including those started from the command line&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
http_proxy=http://myproxy.server.com:8080/
https_proxy=http://myproxy.server.com:8080/
all_proxy=http://myproxy.server.com:8080/
no_proxy=&quot;localhost,127.0.0.1,localaddress,.localdomain.com&quot;


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
GNOME Proxy Settings &lt;/h3&gt;
If you are using a Linux distribution that is running GNOME (for example: Ubuntu, CentOS and RHEL), the &lt;a href=&quot;http://manpages.ubuntu.com/manpages/trusty/en/man1/gsettings.1.html&quot;&gt;proxy settings is controlled from gsettings&lt;/a&gt;. You will need to use these commands&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
gsettings set org.gnome.system.proxy.http host &quot;myproxy.server.com&quot;
gsettings set org.gnome.system.proxy.http port &quot;3128&quot;


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
SOCKS vs HTTP&lt;/h2&gt;
HTTP proxies are clear enough: you want to access websites over http/https, and HTTP proxy servers simply relay the requests across. But it also means you need to make changes to firewall rules to open up a new port for the proxy server.&lt;br /&gt;
&lt;br /&gt;
The SOCKS protocol is designed to work at a lower level, without opening additional ports. For example, &lt;a href=&quot;https://www.ssh.com/ssh/tunneling/example&quot;&gt;ssh natively support SOCKS for port forwarding&lt;/a&gt;, i.e. SSH tunneling.&lt;br /&gt;
&lt;br /&gt;
The tricky bit is how to set SOCKS proxy. Instead of&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
http_proxy=http://myproxy.server.com:8080/


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
append &lt;kbd&gt;socks5&lt;/kbd&gt; in front of the SOCKS server address&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
http_proxy=socks://127.0.0.1:1080


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Likewise in Windows 10 proxy settings, add the prefix &lt;kbd&gt;socks=&lt;/kbd&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8-qZp8QqpiEcHGQnyOAO7epUnPC4KbzjqZV2Oss454D5qb_3DI_8GEnEBo-SJc5TETknYcIO8G-7IabyHp0xcCKZZvpiuWIdzJ1V7lUopuX35LR_rdjFpuNd_4Fus7Dn1r3EzAw/s1600/2019-08-11_Windows_Socks_Proxy_Settings_with_Exclusions.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;483&quot; data-original-width=&quot;491&quot; height=&quot;314&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8-qZp8QqpiEcHGQnyOAO7epUnPC4KbzjqZV2Oss454D5qb_3DI_8GEnEBo-SJc5TETknYcIO8G-7IabyHp0xcCKZZvpiuWIdzJ1V7lUopuX35LR_rdjFpuNd_4Fus7Dn1r3EzAw/s320/2019-08-11_Windows_Socks_Proxy_Settings_with_Exclusions.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Proxychains&lt;/h3&gt;
What if the application you are using does not work with SOCKS protocol? &lt;a href=&quot;https://github.com/rofl0r/proxychains-ng&quot;&gt;You can use Proxychains &lt;/a&gt;to redirect the remote SOCKS/HTTP proxy to your application. For example&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ proxychains4 brew install zsh
[proxychains] config file found: /home/hanxuel.linuxbrew/etc/proxychains.conf


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://flummox-engineering.blogspot.com/2017/10/homebrew-with-shadowsocks-socks5-proxy-vpn-curl-server-aborted-SSL-handshake.html?q=proxychains&quot;&gt;More details in this article&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Proxy Chaining&lt;/h3&gt;
Perhaps the remote proxy uses PAC / WPAD to configure a list of URLS. Or the remote proxy server is very simple, and you want to have fine-grained control over what URLs to go through the proxy server, and what URLs to access directly. &lt;a href=&quot;https://github.com/williambailey/pacproxy&quot;&gt;pacproxy is the perfect tool&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Start Chrome with Command Line Options&lt;/h3&gt;
You can also explicitly tell Chrome to use proxy settings by &lt;a href=&quot;https://www.chromium.org/developers/how-tos/run-chromium-with-flags&quot;&gt;starting Chrome from the command line&lt;/a&gt;.&amp;nbsp; For example:&lt;br /&gt;
&lt;br /&gt;
google-chrome --proxy-server=socks://127.0.0.1:9999&lt;br /&gt;
&lt;br /&gt;
Note that Chrome ignores any local host inclusion for using proxy for security reasons. &lt;a href=&quot;https://flummox-engineering.blogspot.com/2019/08/chrome-ignoring-proxy-settings-for-localhost.html&quot;&gt;Explained in more detail here&lt;/a&gt;. If you must include local addresses, use the &lt;kbd&gt;&amp;lt;-loopback&amp;gt;&lt;/kbd&gt; option&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
google-chrome --proxy-server=socks://10.10.110.28:8080 --proxy-bypass-list=&amp;lt;-loopback&amp;gt;


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk_kzxmKbGhMxDBTt5erOYBusAUrxvHB4CCsPqfG6GVAxXpBlBv9DU88Xbh3-CVc4YmI30PEfR2BKNc7d-JcvUqTfw6dBLCVwaxPvNq9NicoTd6b9eDKPKXo2e3qVvZKbfkI75Fw/s1600/Chrome_Logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1200&quot; data-original-width=&quot;1200&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk_kzxmKbGhMxDBTt5erOYBusAUrxvHB4CCsPqfG6GVAxXpBlBv9DU88Xbh3-CVc4YmI30PEfR2BKNc7d-JcvUqTfw6dBLCVwaxPvNq9NicoTd6b9eDKPKXo2e3qVvZKbfkI75Fw/s320/Chrome_Logo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/2926683319639511439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/2926683319639511439' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2926683319639511439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2926683319639511439'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/08/comprehensive-guide-for-proxy-settings.html' title='Comprehensive Guide for proxy settings for Chrome'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhed9tI7oS4YzNGwRx7EacET82NifFAqq816XiS0yKBc_vW1OswfqS4DjvoEGsi2fJzqPiJNoM9y87SCtOuzTxzmG9ZGGlWyUSOhpJOchVZ8Vs2Xg66e0EQNtGoGwDYu9dFD2rGKQ/s72-c/browser_with_proxy.png" height="72" width="72"/><thr:total>1</thr:total><georss:featurename>Wudaokou, Wu Dao Kou, Haidian Qu, Beijing Shi, China</georss:featurename><georss:point>39.992929 116.337851</georss:point><georss:box>15.360256999999997 75.029257 64.625600999999989 157.646445</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-2927698424596974655</id><published>2019-08-10T13:29:00.001+08:00</published><updated>2019-08-10T13:36:45.197+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ghostscript"/><category scheme="http://www.blogger.com/atom/ns#" term="ImageMagick"/><category scheme="http://www.blogger.com/atom/ns#" term="microsoft office"/><category scheme="http://www.blogger.com/atom/ns#" term="PDF"/><category scheme="http://www.blogger.com/atom/ns#" term="powerpoint"/><title type='text'>How to convert a PDF document into Powerpoint slides</title><content type='html'>We want to convert PDF to Powerpoint slides&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4Wb_hRgvglN3hLxoiCZgaWTLUXxBNlJ_sfXVtB3kCDoeDruJIkFqwrUKyz5XoSFCfuKbQya_Fle1r6BeVRZVURvTn66LxODVCQ663G8tE4C2_FqcD9gLoy-9W2S4OyLSIgWNXeA/s1600/pdf_to_powerpoint_01.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;111&quot; data-original-width=&quot;401&quot; height=&quot;88&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4Wb_hRgvglN3hLxoiCZgaWTLUXxBNlJ_sfXVtB3kCDoeDruJIkFqwrUKyz5XoSFCfuKbQya_Fle1r6BeVRZVURvTn66LxODVCQ663G8tE4C2_FqcD9gLoy-9W2S4OyLSIgWNXeA/s320/pdf_to_powerpoint_01.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
But there is no direct way to convert between the two formats. So let&#39;s break it down into an intermediary step: convert each page in the PDF document into JPG, then import the JPGs into Powerpoint.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigFKxwoMqswpiaNioqcYVRbndRuBL86xc1VAYeOoyXu8JXHpAqZzAOup7-z5HInPAj3kLZ-eWQQy_-oKZXytAaRgaN1kJw8HZxZg2Eq3uJhy-WtJ0S1hW_Tih-TxUbb8VMO5wDBQ/s1600/pdf_to_powerpoint_02.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;114&quot; data-original-width=&quot;701&quot; height=&quot;65&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigFKxwoMqswpiaNioqcYVRbndRuBL86xc1VAYeOoyXu8JXHpAqZzAOup7-z5HInPAj3kLZ-eWQQy_-oKZXytAaRgaN1kJw8HZxZg2Eq3uJhy-WtJ0S1hW_Tih-TxUbb8VMO5wDBQ/s400/pdf_to_powerpoint_02.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Convert PDF to JPG using Ghostscript&lt;/h3&gt;
Ghostscript is the bet tool for converting from PDF or PS into other formats. ImageMagick is the more popular tool, but for PDF conversion it uses Ghostscript in the background.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Before conversion, you need to know a couple of things:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The actual density or dpi for the PDF document&lt;/li&gt;
&lt;li&gt;Quality vs size for the generated image&lt;/li&gt;
&lt;/ul&gt;
This &lt;a href=&quot;https://stackoverflow.com/a/6605085/399759&quot;&gt;StackOverflow answer&lt;/a&gt;, especially the top voted comment has a good explanation on&amp;nbsp; density and quality. Here is a straightforward Ghostscript command for the conversion assuming 200dpi and 100% JPEG quality:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
gs -dNOPAUSE -sDEVICE=jpeg -r200 -dJPEGQ=100 -sOutputFile=document-%02d.jpg &quot;The_Artificial_Intelligence_Crush_2018.pdf&quot; -dBATCH


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
I &lt;a href=&quot;https://hanxue-it.blogspot.com/2019/06/how-to-convert-multi-page-pdf-to-images-in-command-line.html&quot;&gt;wrote about ImageMagick image quality when converting from PDF&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Convert PDF to JPG using ImageMagick&lt;/h3&gt;
&amp;nbsp;Use ImageMagick (with Ghostscript installed) for a more user-friendly format, especially for tuning the quality&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
magick -density 200 -colorspace sRGB &quot;The_Artificial_Intelligence_Crush_2018.pdf&quot; -flatten output-%02d.jpg


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Use &lt;kbd&gt;convert&lt;/kbd&gt; instead of &lt;kbd&gt;magick&lt;/kbd&gt; on Linux and macOS.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Import Images Into Powerpoint&lt;/h3&gt;
Now that you have the images ready, let&#39;s open a new Presentation in Powerpoint, and &lt;b&gt;Insert &lt;/b&gt;→ &lt;b&gt;Photo Album&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAno8oKHC-lBeONZXH1laYQCKVMywzPfoqB1r75vyxbtgbxPZoLJTrtTuZtAe41D2DwPhxqRyRt_j-AeGbyuwWXdI8ref8socO8j2bM_CDR76uc3IEgYWbGJ4YBI4ePfcFxB0cqA/s1600/2019-08-10-Insert_Photo_Album_Powerpoint.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;255&quot; data-original-width=&quot;539&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAno8oKHC-lBeONZXH1laYQCKVMywzPfoqB1r75vyxbtgbxPZoLJTrtTuZtAe41D2DwPhxqRyRt_j-AeGbyuwWXdI8ref8socO8j2bM_CDR76uc3IEgYWbGJ4YBI4ePfcFxB0cqA/s1600/2019-08-10-Insert_Photo_Album_Powerpoint.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Select all the images and click &lt;b&gt;Create&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Sb3Bm4fhkTpaLQsnt51uw8t4hyphenhyphenuEgIr2Z8TKEuKiRI2Corpi9Yp8lsoXygaA4UhfKWX2XyLjV67abW_Bqidc8NQWORAGOq7K_BkY10j4rJEpTFua-gUUYqA7bgeDxCJ1p1nhLA/s1600/2019-08-10-Insert_Photo_Album_Powerpoint_2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;409&quot; data-original-width=&quot;626&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5Sb3Bm4fhkTpaLQsnt51uw8t4hyphenhyphenuEgIr2Z8TKEuKiRI2Corpi9Yp8lsoXygaA4UhfKWX2XyLjV67abW_Bqidc8NQWORAGOq7K_BkY10j4rJEpTFua-gUUYqA7bgeDxCJ1p1nhLA/s1600/2019-08-10-Insert_Photo_Album_Powerpoint_2.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Tada! Your PDF document is now a Powerpoint presentation.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7bA-Sd9qGYR8wmFkxOxDKe7mER8N6-QoEsgFLqPytfioT0Q2W1hS8naZEgCcWJ1S6xheiH8ddoPLrQid6rLmTq4hHq2MiASE1aTm3p1-6KshRIBkqu2eqbEKQAE6wU63M7-irUw/s1600/2019-08-10-Insert_Photo_Album_Powerpoint_3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;908&quot; data-original-width=&quot;1597&quot; height=&quot;362&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7bA-Sd9qGYR8wmFkxOxDKe7mER8N6-QoEsgFLqPytfioT0Q2W1hS8naZEgCcWJ1S6xheiH8ddoPLrQid6rLmTq4hHq2MiASE1aTm3p1-6KshRIBkqu2eqbEKQAE6wU63M7-irUw/s640/2019-08-10-Insert_Photo_Album_Powerpoint_3.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
How About macOS?&lt;/h3&gt;
If you are using macOS, there is good news and bad news. The good news is exporting images from PDF is a breeze using Preview. View Thumbnails in Preview, or press &lt;kbd&gt;⌘&lt;/kbd&gt; + &lt;kbd&gt;⌥&lt;/kbd&gt; + &lt;kbd&gt;1&lt;/kbd&gt;. Then select all the images and File → Export. The &lt;a href=&quot;https://support.apple.com/en-sg/guide/preview/prvw15636/mac&quot;&gt;Preview User Guide&lt;/a&gt; has a section titled &lt;b&gt;Extract a PDF page as an image&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
The bad news is Powerpoint for Mac still does not have the &lt;i&gt;Insert Photo Album&lt;/i&gt; functionality. You can either &lt;a href=&quot;http://www.pptfaq.com/FAQ00050_BATCH_IMPORT_images_into_PowerPoint.htm&quot;&gt;use&lt;/a&gt; &lt;a href=&quot;https://www.youtube.com/watch?v=5VEdJvVOOLY&quot;&gt;Automator&lt;/a&gt;, or create the slides in Keynote, then export to PPT. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/2927698424596974655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/2927698424596974655' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2927698424596974655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2927698424596974655'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/08/how-to-convert-pdf-document-into-Powerpoint-slides.html' title='How to convert a PDF document into Powerpoint slides'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4Wb_hRgvglN3hLxoiCZgaWTLUXxBNlJ_sfXVtB3kCDoeDruJIkFqwrUKyz5XoSFCfuKbQya_Fle1r6BeVRZVURvTn66LxODVCQ663G8tE4C2_FqcD9gLoy-9W2S4OyLSIgWNXeA/s72-c/pdf_to_powerpoint_01.png" height="72" width="72"/><thr:total>1</thr:total><georss:featurename>Wudaokou, Haidian, Beijing, China</georss:featurename><georss:point>39.992419 116.33937000000003</georss:point><georss:box>39.9680885 116.29902950000003 40.016749499999996 116.37971050000003</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-1034629773829542946</id><published>2019-07-23T08:00:00.000+08:00</published><updated>2019-07-23T08:01:59.515+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="vue.js"/><category scheme="http://www.blogger.com/atom/ns#" term="vuepress"/><title type='text'>Vuepress: How to embed video in markdown</title><content type='html'>With Vuepress is you can start creating content in Markdown out of the box. And Markdown has tons of useful plugin. When I was updating the &lt;a href=&quot;https://www.wujiquan.net/&quot;&gt;Wujiquan website&lt;/a&gt;, I wanted to embed videos into the content. While it is possible to add html tags directly within markdown, I want to keep the content clean and simple.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
markdown-it-html5-embed&lt;/h3&gt;
Vuepress supports &lt;a href=&quot;https://www.npmjs.com/search?q=keywords:markdown-it-plugin&quot;&gt;markdown-it plugins&lt;/a&gt;, and &lt;a href=&quot;https://github.com/cmrd-senya/markdown-it-html5-embed&quot;&gt;https://github.com/cmrd-senya/markdown-it-html5-embed&lt;/a&gt; comes to the rescue! Adding&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
![6 healing sounds video](https://wujiquan.sgp1.digitaloceanspaces.com/Qigong/Wujiquan-six-healing-sounds.mp4)


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
to the page will render the following in HTML&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
&amp;amp;lt;source type=&amp;amp;quot;video/mp4&amp;amp;quot; src=&amp;amp;quot;https://wujiquan.sgp1.digitaloceanspaces.com/Qigong/Wujiquan-six-healing-sounds.mp4&amp;amp;quot;&amp;amp;gt;
Your browser does not support playing HTML5 video. You can &amp;amp;lt;a href=&amp;amp;quot;https://wujiquan.sgp1.digitaloceanspaces.com/Qigong/Wujiquan-six-healing-sounds.mp4&amp;amp;quot; download=&amp;amp;quot;&amp;amp;quot;&amp;amp;gt;download a copy of the video file&amp;amp;lt;/a&amp;amp;gt; instead.
Here is a description of the content: 6 healing sounds video


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIjtSN4XKeiYUoJi3NmAy8KcXDkc04j_wfaEGZkEJmtlppLX3-sEwKTFDtRFr_nkc8sF8b3LmfR65tOKt575oFvQE-ovbdOOXsnShXSVz7-oH36AoH1XDY2-ifP0-KZq8VR3VGhQ/s1600/2019-07-22_Wujiquan_Site_Embed_Video.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;638&quot; data-original-width=&quot;835&quot; height=&quot;488&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIjtSN4XKeiYUoJi3NmAy8KcXDkc04j_wfaEGZkEJmtlppLX3-sEwKTFDtRFr_nkc8sF8b3LmfR65tOKt575oFvQE-ovbdOOXsnShXSVz7-oH36AoH1XDY2-ifP0-KZq8VR3VGhQ/s640/2019-07-22_Wujiquan_Site_Embed_Video.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Adding Markdown Plugin to Vuepress&lt;/h3&gt;
&amp;nbsp;To add the &lt;kbd&gt;markdown-it-html5-embed&lt;/kbd&gt; plugin, first add the package to your vuepress project&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
yarn add markdown-it-html5-embed


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Then edit your &lt;kbd&gt;config.js&lt;/kbd&gt; and add the following code&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-js&quot;&gt;&lt;code&gt;
module.exports = {
&amp;nbsp; markdown: {
&amp;nbsp;&amp;nbsp;&amp;nbsp; extendMarkdown: md =&amp;gt; {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; md.use(require(&#39;markdown-it-html5-embed&#39;), {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; html5embed: {
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; useImageSyntax: true,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; useLinkSyntax: false
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; })
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&amp;nbsp; },


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
For more information on the syntax, refer to the &lt;a href=&quot;https://github.com/cmrd-senya/markdown-it-html5-embed&quot;&gt;markdown-it-html5-embed documentation&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm6pnm3bfgAya4UBm5df5lbryx_Q6eQO4OikHCjXqRMPt7BoLRAxf7_2loki1YZuTxPUIjIZet822uuHMacPWEqvdQJhpJAc_vo_JFNCQJtNNHtrRNhSB5leGAusR40WOCn6Xrmg/s1600/vuepress-logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;600&quot; data-original-width=&quot;600&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm6pnm3bfgAya4UBm5df5lbryx_Q6eQO4OikHCjXqRMPt7BoLRAxf7_2loki1YZuTxPUIjIZet822uuHMacPWEqvdQJhpJAc_vo_JFNCQJtNNHtrRNhSB5leGAusR40WOCn6Xrmg/s320/vuepress-logo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/1034629773829542946/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/1034629773829542946' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/1034629773829542946'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/1034629773829542946'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/07/vuepress-how-to-embed-video-in-markdown.html' title='Vuepress: How to embed video in markdown'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIjtSN4XKeiYUoJi3NmAy8KcXDkc04j_wfaEGZkEJmtlppLX3-sEwKTFDtRFr_nkc8sF8b3LmfR65tOKt575oFvQE-ovbdOOXsnShXSVz7-oH36AoH1XDY2-ifP0-KZq8VR3VGhQ/s72-c/2019-07-22_Wujiquan_Site_Embed_Video.png" height="72" width="72"/><thr:total>2</thr:total><georss:featurename>Wudaokou, Wu Dao Kou, Haidian Qu, Beijing Shi, China</georss:featurename><georss:point>39.992929 116.337851</georss:point><georss:box>15.360253999999998 75.029257 64.625604 157.646445</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-6153523694241249129</id><published>2019-07-22T16:00:00.000+08:00</published><updated>2019-07-22T16:00:02.910+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cmder"/><category scheme="http://www.blogger.com/atom/ns#" term="vscode"/><title type='text'>How To Change Visual Studio Code&#39;s Default Shell to Cmder</title><content type='html'>Visual Studio Code&#39;s default Shell in Windows is PowerShell&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIdKZt3CBSJDzuJ6HvVqcZ-gCvsfZHIr3ojrNLySBVVD1NSqxGcuzf1nlu8taJRRlClFGOVAeVgd4MH_iWLtp1G2uhN9s1A2UqD7j3JWpr2PAeJZpbCdN3eGCtVnHaPjBUrZ2hKg/s1600/2019-07-21_vscode_cmder_01.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;321&quot; data-original-width=&quot;1042&quot; height=&quot;196&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIdKZt3CBSJDzuJ6HvVqcZ-gCvsfZHIr3ojrNLySBVVD1NSqxGcuzf1nlu8taJRRlClFGOVAeVgd4MH_iWLtp1G2uhN9s1A2UqD7j3JWpr2PAeJZpbCdN3eGCtVnHaPjBUrZ2hKg/s640/2019-07-21_vscode_cmder_01.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
There are better alternatives to &lt;kbd&gt;PowerShell&lt;/kbd&gt; or &lt;kbd&gt;cmd.exe&lt;/kbd&gt; in Windows. My favourite is &lt;a href=&quot;https://github.com/cmderdev/cmder&quot;&gt;Cmder&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Presumably you already have Cmder installed in your system, in a &lt;b&gt;path without space&lt;/b&gt;, for example &lt;kbd&gt;C:\Tools\Cmder&lt;/kbd&gt;. &lt;a href=&quot;https://chocolatey.org/&quot;&gt;Chocolatey&lt;/a&gt;&#39;s Cmder installation works perfectly fine.&amp;nbsp; &lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Change Default Shell&lt;/h3&gt;To change Visual Studio Code&#39;s default shell, go to Preferences and edit &lt;kbd&gt;settings.json&lt;/kbd&gt;. Add the following lines, changing the path where Cmder is installed&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, &#39;Courier New&#39;, monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;terminal.integrated.shell.windows&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;cmd.exe&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;terminal.integrated.env.windows&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;CMDER_ROOT&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;C:&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;tools&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;Cmder&quot;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    },&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;terminal.integrated.shellArgs.windows&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: [&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;/k C:&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;tools&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;Cmder&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;vendor&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;init.bat&quot;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    ],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
Important: you need to set &lt;kbd&gt;cmd.exe&lt;/kbd&gt;. Setting &lt;kbd&gt;Cmder.exe&lt;/kbd&gt; will not work&lt;br /&gt;
&lt;br /&gt;
Now you can have all the goodness of Cmder within vscode, such as built-in git integration.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfcwSoW43txWLcwEdjxIPg9Dcqcg84U-7elGpfeL_c3am6RTbWOgq9UCc0k-yyMrufr5zRaM-QpkxzdSMyOYydxOSUjQEhmIYO7wSkorFOYNZZPkj4qSJPp5mp-QF5oVAPlXNmcA/s1600/2019-07-21_vscode_cmder_02.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;370&quot; data-original-width=&quot;1036&quot; height=&quot;228&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfcwSoW43txWLcwEdjxIPg9Dcqcg84U-7elGpfeL_c3am6RTbWOgq9UCc0k-yyMrufr5zRaM-QpkxzdSMyOYydxOSUjQEhmIYO7wSkorFOYNZZPkj4qSJPp5mp-QF5oVAPlXNmcA/s640/2019-07-21_vscode_cmder_02.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3&gt;PowerShell in Cmder&lt;/h3&gt;You can also change your default shell from the cmd.exe/bash default to PowerShell within Cmder. Use the following &lt;kbd&gt;settings.json&lt;/kbd&gt; in vscode&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: #1e1e1e; color: #d4d4d4; font-family: Consolas, &#39;Courier New&#39;, monospace; font-size: 14px; font-weight: normal; line-height: 19px; white-space: pre;&quot;&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;terminal.integrated.shell.windows&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;C:&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;WINDOWS&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;System32&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;WindowsPowerShell&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;v1.0&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;powershell.exe&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;,&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;terminal.integrated.env.windows&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;CMDER_ROOT&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;C:&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;tools&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;Cmder&quot;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    },&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    &lt;/span&gt;&lt;span style=&quot;color: #9cdcfe;&quot;&gt;&quot;terminal.integrated.shellArgs.windows&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;: [&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;-ExecutionPolicy&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;Bypass&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;-NoLogo&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;-NoProfile&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;-NoExit&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;      &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;-Command&quot;&lt;/span&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;&quot;. &#39;C:&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;tools&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;cmder&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;vendor&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;conemu-maximus5&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;..&lt;/span&gt;&lt;span style=&quot;color: #d7ba7d;&quot;&gt;\\\\&lt;/span&gt;&lt;span style=&quot;color: #ce9178;&quot;&gt;profile.ps1&#39;&quot;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;color: #d4d4d4;&quot;&gt;    ],&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU0DOAhYcNjEt_sJYFESzfMJqfQs6dUL3ZNEUmWZHsn_XvHRM0wIJz76H4MKPOBLzH7iW3R9OwdBI_8p_PIqkrBooUCQW4M_wfvfAoV_oLgwyIfQ3HAWPhEqFl7_oOKR1r2Bz2Mw/s1600/vscode_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;494&quot; data-original-width=&quot;452&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiU0DOAhYcNjEt_sJYFESzfMJqfQs6dUL3ZNEUmWZHsn_XvHRM0wIJz76H4MKPOBLzH7iW3R9OwdBI_8p_PIqkrBooUCQW4M_wfvfAoV_oLgwyIfQ3HAWPhEqFl7_oOKR1r2Bz2Mw/s320/vscode_logo.png&quot; width=&quot;292&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/6153523694241249129/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/6153523694241249129' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/6153523694241249129'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/6153523694241249129'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/07/how-to-change-visual-studio-codes-default-shell-to-cmder.html' title='How To Change Visual Studio Code&#39;s Default Shell to Cmder'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIdKZt3CBSJDzuJ6HvVqcZ-gCvsfZHIr3ojrNLySBVVD1NSqxGcuzf1nlu8taJRRlClFGOVAeVgd4MH_iWLtp1G2uhN9s1A2UqD7j3JWpr2PAeJZpbCdN3eGCtVnHaPjBUrZ2hKg/s72-c/2019-07-21_vscode_cmder_01.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>Wudaokou, Wu Dao Kou, Haidian Qu, Beijing Shi, China</georss:featurename><georss:point>39.992929 116.337851</georss:point><georss:box>15.360254499999996 75.029257 64.6256035 157.646445</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-2555757353851626355</id><published>2019-07-21T19:41:00.002+08:00</published><updated>2019-07-21T19:41:44.953+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="github"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><title type='text'>Automated Security Fixes on Github</title><content type='html'>It&#39;s been a while since I have worked on open source projects. When I logged on to my project&#39;s Github page, I was pleasantly surprised to see this warning:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHb1xs7nd08YT1YDIaAKTUGEL6KRrntwLg_QK0jnJPjgMERS44rGyObP-xjATKaK8lC3F2O-sXZfJUct4TO9ksKryWnLpkz3D-7igcpqFg6qDOlB1ZNDG0OU67brhkqoxP91rd0A/s1600/2019-07-21_github_security_01.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;355&quot; data-original-width=&quot;1035&quot; height=&quot;218&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHb1xs7nd08YT1YDIaAKTUGEL6KRrntwLg_QK0jnJPjgMERS44rGyObP-xjATKaK8lC3F2O-sXZfJUct4TO9ksKryWnLpkz3D-7igcpqFg6qDOlB1ZNDG0OU67brhkqoxP91rd0A/s640/2019-07-21_github_security_01.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
A bit of Googling showed that &lt;a href=&quot;https://help.github.com/en/articles/about-security-alerts-for-vulnerable-dependencies&quot;&gt;Github has started to automatically scan for outdated dependencies with security vulnerabilities&lt;/a&gt;.Clicking on the alert will show which packages that are impacted.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjVSfX0vyf0zhDD_SvQHRabCK4S4JyVOz-r86BEFJH30Ul_3OAM29_ywlJQydA9ZqvC6FCV67uO0BGKt-yEwsNtV7kEelFcjahCnbBW2p9RlHQZlZjW1hQMGsxyrJv8X-1FGe68Q/s1600/2019-07-21_github_security_02.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;377&quot; data-original-width=&quot;782&quot; height=&quot;308&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjVSfX0vyf0zhDD_SvQHRabCK4S4JyVOz-r86BEFJH30Ul_3OAM29_ywlJQydA9ZqvC6FCV67uO0BGKt-yEwsNtV7kEelFcjahCnbBW2p9RlHQZlZjW1hQMGsxyrJv8X-1FGe68Q/s640/2019-07-21_github_security_02.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Github also helpfully show exactly what are the vulnerabilities&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgccqbGhETuXO8jOF4ilAIc64RjsZl_0p55Dw3RxX09QDh9kR8Lh3CbsqHUJWXI3kaIp89RsEzNILkAjFneTNaOmdnxagbwSl_zVA1q4MWVgBMM8eStKlqw22Rgstg_li6lNjwIfw/s1600/2019-07-21_github_security_03.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;695&quot; data-original-width=&quot;781&quot; height=&quot;568&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgccqbGhETuXO8jOF4ilAIc64RjsZl_0p55Dw3RxX09QDh9kR8Lh3CbsqHUJWXI3kaIp89RsEzNILkAjFneTNaOmdnxagbwSl_zVA1q4MWVgBMM8eStKlqw22Rgstg_li6lNjwIfw/s640/2019-07-21_github_security_03.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Automated Security Fix&lt;/h3&gt;
What&#39;s even better &lt;a href=&quot;https://help.github.com/en/articles/configuring-automated-security-fixes&quot;&gt;is the automated security fix feature&lt;/a&gt;. You will need to turn it on for your repository though.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4BWS11Kg0FvbXHpZkd9bm8z1O_ZqAn753JA2HC9vtEpRq0dOFmmtchJUWQXuHuK2CWDGTF6N50Oi6NJHQ5ETjZlCZsI4dWteJkyPSZWk9UanM5j7mSY6-YeWkM-h9UYInwwQ6hg/s1600/2019-07-21_github_security_04.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;237&quot; data-original-width=&quot;524&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4BWS11Kg0FvbXHpZkd9bm8z1O_ZqAn753JA2HC9vtEpRq0dOFmmtchJUWQXuHuK2CWDGTF6N50Oi6NJHQ5ETjZlCZsI4dWteJkyPSZWk9UanM5j7mSY6-YeWkM-h9UYInwwQ6hg/s1600/2019-07-21_github_security_04.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
If you choose not to have automated fixes, you still can manually trigger the fix by using the &lt;b&gt;Create automated security fix&lt;/b&gt; functionality.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2q2CUFTuo2gD9tfrypVpIMVhuqWet9HdQRlGRXXMBWQr0lZM_4_Y8T7PtrRJevUrjTTvRm3_3YoNboylkW76m286jh2AosD3hVqUUKPxCHqvmppXcGK_ChTOVyLuKmsY4kK6fXw/s1600/2019-07-21_github_security_05.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;302&quot; data-original-width=&quot;797&quot; height=&quot;242&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2q2CUFTuo2gD9tfrypVpIMVhuqWet9HdQRlGRXXMBWQr0lZM_4_Y8T7PtrRJevUrjTTvRm3_3YoNboylkW76m286jh2AosD3hVqUUKPxCHqvmppXcGK_ChTOVyLuKmsY4kK6fXw/s640/2019-07-21_github_security_05.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
A pull request will be automatically generated.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHkDZg36ZrZVtlJd_jl7hEVRIJF-WxSKOyaM8FBeQFxNhgYR9_PI6mmSCAWOgyFnBJXBnmpL4aIwqoqgt4KfatVmtHguhkI3xS_9br-C2uqoEgEkUa6U8BM0D_qGw9In86t9Xwvg/s1600/2019-07-21_github_security_06.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;626&quot; data-original-width=&quot;1052&quot; height=&quot;380&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHkDZg36ZrZVtlJd_jl7hEVRIJF-WxSKOyaM8FBeQFxNhgYR9_PI6mmSCAWOgyFnBJXBnmpL4aIwqoqgt4KfatVmtHguhkI3xS_9br-C2uqoEgEkUa6U8BM0D_qGw9In86t9Xwvg/s640/2019-07-21_github_security_06.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
While it is nice for Github to generate security fixes, we should not be depending on 3rd parties for our project&#39;s security. Use a tool such as &lt;a href=&quot;https://yarnpkg.com/lang/en/docs/cli/audit/&quot;&gt;yarn audit&lt;/a&gt; to keep your project constantly up to date and secure.&amp;nbsp; &lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/2555757353851626355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/2555757353851626355' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2555757353851626355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2555757353851626355'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/07/automated-security-fixes-on-github.html' title='Automated Security Fixes on Github'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHb1xs7nd08YT1YDIaAKTUGEL6KRrntwLg_QK0jnJPjgMERS44rGyObP-xjATKaK8lC3F2O-sXZfJUct4TO9ksKryWnLpkz3D-7igcpqFg6qDOlB1ZNDG0OU67brhkqoxP91rd0A/s72-c/2019-07-21_github_security_01.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>Wudaokou, Wu Dao Kou, Haidian Qu, Beijing Shi, China</georss:featurename><georss:point>39.992929 116.337851</georss:point><georss:box>15.360254499999996 75.029257 64.6256035 157.646445</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-5957699780162168722</id><published>2019-07-18T18:38:00.001+08:00</published><updated>2019-07-18T18:38:15.443+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="macos"/><title type='text'>How to check the number of CPUs and cores</title><content type='html'>How do you check for the number of CPUs and cores? From &lt;kbd&gt;/proc/cpuinfo&lt;/kbd&gt;?&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ grep -c ^processor /proc/cpuinfo
56
$ cat /proc/cpuinfo | awk &#39;/^processor/{print $3}&#39; | wc -l
56


&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
They will return twice the number if hyperthreading is enabled. How about using &lt;kbd&gt;nproc&lt;/kbd&gt;?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ nproc --all
56


&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Still the same. Not accurate if hyperthreading is enabled.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h2&gt;
getconf&lt;/h2&gt;
&lt;div&gt;
The &lt;kbd&gt;getconf&lt;/kbd&gt; command works great because it is available on both Linux and MacOS. &lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ getconf _NPROCESSORS_ONLN
56


&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Unfortunately it only returns the number of virtual cores. &lt;/div&gt;
&lt;h2&gt;
lscpu and sysctl&lt;/h2&gt;
&lt;div&gt;
Another problem is the output from &lt;kbd&gt;/proc/cpuinfo&lt;/kbd&gt; is meant to be read by humans, and hence may change across version. Not suitable for parsing and using it in scripts. &lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You should be using &lt;kbd&gt;lscpu&lt;/kbd&gt; instead. Or &lt;kbd&gt;sysctl&lt;/kbd&gt; on MacOS. This &lt;a href=&quot;https://stackoverflow.com/a/23378780/399759&quot;&gt;script from Stackoverflow&lt;/a&gt; by the user &lt;a href=&quot;https://stackoverflow.com/users/45375/mklement0&quot;&gt;mklement0&lt;/a&gt;&amp;nbsp;counts the number of logical and physical CPU&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
#!/bin/sh

# macOS:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Use `sysctl -n hw.*cpu_max`, which returns the values of&amp;nbsp;
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; interest directly.
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; CAVEAT: Using the &quot;_max&quot; key suffixes means that the *maximum*
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; available number of CPUs is reported, whereas the
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; current power-management mode could make *fewer* CPUs&amp;nbsp;
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; available; dropping the &quot;_max&quot; suffix would report the
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; number of *currently* available ones; see [1] below

#
# Linux:&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Parse output from `lscpu -p`, where each output line represents
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; a distinct (logical) CPU.
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Note: Newer versions of `lscpu` support more flexible output
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; formats, but we stick with the parseable legacy format&amp;nbsp;

#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; generated by `-p` to support older distros, too.
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; `-p` reports *online* CPUs only - i.e., on hot-pluggable&amp;nbsp;
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; systems, currently disabled (offline) CPUs are NOT
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; reported.

# Number of LOGICAL CPUs (includes those reported by hyper-threading cores)
&amp;nbsp; # Linux: Simply count the number of (non-comment) output lines from `lscpu -p`,&amp;nbsp;
&amp;nbsp; # which tells us the number of *logical* CPUs.
logicalCpuCount=$([ $(uname) = &#39;Darwin&#39; ] &amp;amp;&amp;amp;&amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sysctl -n hw.logicalcpu_max ||&amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;lscpu -p | egrep -v &#39;^#&#39; | wc -l)


# Number of PHYSICAL CPUs (cores).
&amp;nbsp; # Linux: The 2nd column contains the core ID, with each core ID having 1 or
&amp;nbsp; #&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; - in the case of hyperthreading - more logical CPUs.
&amp;nbsp; #&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Counting the *unique* cores across lines tells us the
&amp;nbsp; #&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; number of *physical* CPUs (cores).
physicalCpuCount=$([ $(uname) = &#39;Darwin&#39; ] &amp;amp;&amp;amp;&amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;sysctl -n hw.physicalcpu_max ||
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;lscpu -p | egrep -v &#39;^#&#39; | sort -u -t, -k 2,4 | wc -l)

# Print the values.
cat &amp;lt;&amp;lt;EOF
# of logical CPUs:&amp;nbsp; $logicalCpuCount
# of physical CPUS: $physicalCpuCount
EOF


&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyq-WkSP0B6_84J_yM9T2sQZMEZiUBWuVxuXSILPFOLL9PbFBZUCvpOGUQxX5hR4-Xa4IWiRNztoiXaZjT00GjyLrtLm9T4XEkQSnYGVWP_UI5gxj-S5fPHUpSYGc5u9wiXvQPjQ/s1600/linux_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;317&quot; data-original-width=&quot;640&quot; height=&quot;158&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyq-WkSP0B6_84J_yM9T2sQZMEZiUBWuVxuXSILPFOLL9PbFBZUCvpOGUQxX5hR4-Xa4IWiRNztoiXaZjT00GjyLrtLm9T4XEkQSnYGVWP_UI5gxj-S5fPHUpSYGc5u9wiXvQPjQ/s320/linux_logo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/5957699780162168722/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/5957699780162168722' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/5957699780162168722'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/5957699780162168722'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/07/how-to-check-number-of-cpus-and-cores.html' title='How to check the number of CPUs and cores'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhyq-WkSP0B6_84J_yM9T2sQZMEZiUBWuVxuXSILPFOLL9PbFBZUCvpOGUQxX5hR4-Xa4IWiRNztoiXaZjT00GjyLrtLm9T4XEkQSnYGVWP_UI5gxj-S5fPHUpSYGc5u9wiXvQPjQ/s72-c/linux_logo.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>Wudaokou, Haidian, Beijing, China</georss:featurename><georss:point>39.992419 116.33937000000003</georss:point><georss:box>39.9680885 116.29902950000003 40.016749499999996 116.37971050000003</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-7485380838502562950</id><published>2019-07-17T17:05:00.000+08:00</published><updated>2019-07-24T15:28:32.346+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="kernel"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Security"/><title type='text'>How to allow a non-root process to listen to a port below 1024</title><content type='html'>Linux does not allow for user processes to listen to a port below 1024. This is by design. Specifically in the file &lt;kbd&gt;net/ipv4/af_inet.c&lt;/kbd&gt; , these lines perform the check&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-c&quot;&gt;&lt;code&gt;
if (snum &amp;amp;&amp;amp; snum &amp;lt; PROT_SOCK &amp;amp;&amp;amp; !capable(CAP_NET_BIND_SERVICE))
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
The security reasoning is misguided in 2019. Malware writers and other bad actors cannot care less what port your process is running on: as long as they can take control of the process and your process has a lot of privileges, then your system will be compromised. But I digress.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;setcap&lt;/h3&gt;The best method to overcome this limitation is to use the &lt;b&gt;setcap&lt;/b&gt;&amp;nbsp;command&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo setcap &#39;cap_net_bind_service=+ep&#39; /scratch/spiped


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Note that &lt;kbd&gt;sudo&lt;/kbd&gt; or &lt;b&gt;root&lt;/b&gt; permission is required when running &lt;kbd&gt;setcap&lt;/kbd&gt;&amp;nbsp;or else you will see this message&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ setcap &#39;cap_net_bind_service=+ep&#39; /scratch/spiped
unable to set CAP_SETFCAP effective capability: Operation not permitted


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;Due to setcap&#39;s limitation, the command can only work on a local filesystem. When I run the command on my NFS-mounted home directory, I see this error&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ sudo setcap &#39;cap_net_bind_service=+ep&#39; ~/bin/spiped
Password:&amp;nbsp;
Failed to set capabilities on file `/home/hanxue/bin/spiped&#39; (Operation not supported)


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
For more information, &lt;a href=&quot;http://man7.org/linux/man-pages/man8/setcap.8.html&quot;&gt;refer to the setcap manual&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;iptables&lt;/h3&gt;&lt;div&gt;You can re-route local connections from one port to another port. Note that the following will NOT work for local connections&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 25 -j REDIRECT --to-port 8025


&lt;/code&gt;&lt;/pre&gt;You need &lt;kbd&gt;PREROUTING&lt;/kbd&gt; for local connections&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
iptables -A PREROUTING -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -A OUTPUT -t nat -p tcp --dport 80 -j REDIRECT --to-port 8080


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;SSH Tunnel&lt;/h3&gt;&lt;div&gt;This sounds a bit silly, but you can open an SSH connection to the same machine, routing the port&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo ssh localhost -L 25:localhost:8025 -N


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;authbind&lt;/h3&gt;Alternatively, use &lt;kbd&gt;authbind&lt;/kbd&gt;. Configure port 25 for access to all users&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo touch /etc/authbind/byport/25
sudo chmod 777 /etc/authbind/byport/25


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Then run the &quot;authbind&quot; command&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
authbind --deep /scratch/spiped --with --your --arguments


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Hack the Linux Kernel&lt;/h3&gt;&lt;div&gt;That&#39;s the advantage of working with open source software; when all easy options fails, you can edit the source code.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Remove the &lt;kbd&gt;1024&lt;/kbd&gt; port restriction and change it to &lt;kbd&gt;0&lt;/kbd&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-c&quot;&gt;&lt;code&gt;
# /usr/src/linux-[version_number]/include/net/sock.h:
/* Sockets 0-1023 can&#39;t be bound to unless you are superuser */
#define PROT_SOCK&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;1024


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Or in the aforementioned &lt;kbd&gt;net/ipv4/af_inet.c&lt;/kbd&gt; file&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-c&quot;&gt;&lt;code&gt;
#if (snum &amp;amp;&amp;amp; snum &amp;lt; PROT_SOCK &amp;amp;&amp;amp; !capable(CAP_NET_BIND_SERVICE))
#&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; goto out;



&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
This really should be the last resort: who knows if there are any sloppy developers that count on listening to ports below 1024 to &lt;i&gt;fail&lt;/i&gt;&amp;nbsp;for their application to work ;-)&lt;br /&gt;
&lt;br /&gt;
By the way, I was trying to relay mail delivery from one server to another server using spiped&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj864xYbotDTaVT0lijIUJOzkXVnjsmiI1Z4f2jxANG8WPrNz-bDU231gV7ss74bUMhHbApT5M9wIBURPAcRtaL_VnFzMNTAKT1HVBnstfN7FrNXEYAEE_yj_hdes1p9Yg5VDyNsg/s1600/spiped-smtp.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;315&quot; data-original-width=&quot;652&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj864xYbotDTaVT0lijIUJOzkXVnjsmiI1Z4f2jxANG8WPrNz-bDU231gV7ss74bUMhHbApT5M9wIBURPAcRtaL_VnFzMNTAKT1HVBnstfN7FrNXEYAEE_yj_hdes1p9Yg5VDyNsg/s1600/spiped-smtp.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrMWm163ztduVWsXs9D8-5kqUyiSplSU5btnMCn74oSvUdpJubXoE4NwFyW2oFtep4PsvpFiTjQfY8CRTkd9aatWXXN1ow9Hkju_Ojasy4lMbqLuG8-9hZ7t_7rQvEwneA2_0vrg/s1600/linux_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;317&quot; data-original-width=&quot;640&quot; height=&quot;158&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrMWm163ztduVWsXs9D8-5kqUyiSplSU5btnMCn74oSvUdpJubXoE4NwFyW2oFtep4PsvpFiTjQfY8CRTkd9aatWXXN1ow9Hkju_Ojasy4lMbqLuG8-9hZ7t_7rQvEwneA2_0vrg/s320/linux_logo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/7485380838502562950/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/7485380838502562950' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/7485380838502562950'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/7485380838502562950'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/07/how-to-allow-non-root-process-to-listen-to-a-port-below-2014.html' title='How to allow a non-root process to listen to a port below 1024'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj864xYbotDTaVT0lijIUJOzkXVnjsmiI1Z4f2jxANG8WPrNz-bDU231gV7ss74bUMhHbApT5M9wIBURPAcRtaL_VnFzMNTAKT1HVBnstfN7FrNXEYAEE_yj_hdes1p9Yg5VDyNsg/s72-c/spiped-smtp.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>Wudaokou, Haidian, Beijing, China</georss:featurename><georss:point>39.992419 116.33937000000003</georss:point><georss:box>39.9680885 116.29902950000003 40.016749499999996 116.37971050000003</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-4034023646076739026</id><published>2019-07-03T13:22:00.000+08:00</published><updated>2019-07-03T13:22:05.694+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Chrome"/><title type='text'>Chrome&#39;s History and Usage Trends</title><content type='html'>Google &lt;a href=&quot;https://myactivity.google.com/item?restrict=waa&amp;amp;utm_source=retention-promo&quot;&gt;used to show the days and times when I most frequently use Search&lt;/a&gt;. I like to be able to see when I am most active and what are my usage trends over time. Unfortunately the feature has been taken away.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;History Trends Unlimited&lt;/h3&gt;Thankfully there is &lt;a href=&quot;https://chrome.google.com/webstore/detail/history-trends-unlimited/pnmchffiealhkdloeffcdnbgdnedheme/related&quot;&gt;History Trends Unlimited Chrome extension&lt;/a&gt;. It will automatically pull your full Chrome history and present them in an informative manner.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIL5JGyDvhMzGAJtueDr9Q3VUPX6QfzIcF-jXF4gYSLtrBXtfXA1jvMvI3FZ2dLpE_67JWc9sQuzgFRR8g9f4ClQ31UpTW1Ste1J4EVCAtxZ-sm6EOC0QNl1DtK4DbHNACepxQ_Q/s1600/History_Trends_Unlimited_hanxue_2019-06-29.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1600&quot; data-original-width=&quot;663&quot; height=&quot;640&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIL5JGyDvhMzGAJtueDr9Q3VUPX6QfzIcF-jXF4gYSLtrBXtfXA1jvMvI3FZ2dLpE_67JWc9sQuzgFRR8g9f4ClQ31UpTW1Ste1J4EVCAtxZ-sm6EOC0QNl1DtK4DbHNACepxQ_Q/s640/History_Trends_Unlimited_hanxue_2019-06-29.png&quot; width=&quot;264&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;I can see roughly when are the times when I am at work, and what are the top sites that I visit.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h3 style=&quot;clear: both; text-align: left;&quot;&gt;Unlimited History&lt;/h3&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;Chrome&#39;s history of the sites you have visited will only be stored for 90 days. Beyond that the older data is deleted. What&#39;s great with this extension is it will keep your history beyond 90 days - henec the name &quot;Unlimited&quot;.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h3 style=&quot;clear: both; text-align: left;&quot;&gt;Export History&lt;/h3&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;In case you need to export your &lt;i&gt;complete&amp;nbsp;&lt;/i&gt;browser history, the extension let&#39;s you do that. You can also automatically back up your history in a fixed interval.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjovcxEk55_5mdUcxWteGjpesrnVtn6QQ40v_03TB_Rs7dmgqVrCRwuFEVyne17HtsXxaD_kdOJJIIT0_8Ws4V7S4AViCii2kTJmY9vHWjS44J7Oy33MDO-zwfyx40EKN6cgih9Ww/s1600/2019-06-29+13_15_38-History+Trends+Unlimited_+Options.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;243&quot; data-original-width=&quot;806&quot; height=&quot;192&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjovcxEk55_5mdUcxWteGjpesrnVtn6QQ40v_03TB_Rs7dmgqVrCRwuFEVyne17HtsXxaD_kdOJJIIT0_8Ws4V7S4AViCii2kTJmY9vHWjS44J7Oy33MDO-zwfyx40EKN6cgih9Ww/s640/2019-06-29+13_15_38-History+Trends+Unlimited_+Options.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;History Unlimited options&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;Feel free to explore the export options - fantastic to perform analysis on your web browsing behaviour.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/history-trends-unlimited/pnmchffiealhkdloeffcdnbgdnedheme&quot; target=&quot;_blank&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img alt=&quot;Link to Chrome Web Store&quot; border=&quot;0&quot; data-original-height=&quot;150&quot; data-original-width=&quot;496&quot; height=&quot;96&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLZVmzg6UEyk56nxiUjy0u_xsade1R6F5RYizbP4XC7NNaM8qGvdMKda_txtY0gNGVUNYWaa1i2AcSHHmCATtyUZsmxYDP9rw0XWuq632Vq1ILglbiHPpvXq0qAnffkNzL3iQKuA/s320/ChromeWebStore_Badge_496x150.png&quot; title=&quot;&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/4034023646076739026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/4034023646076739026' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/4034023646076739026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/4034023646076739026'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/07/chromes-history-and-usage-trends.html' title='Chrome&#39;s History and Usage Trends'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIL5JGyDvhMzGAJtueDr9Q3VUPX6QfzIcF-jXF4gYSLtrBXtfXA1jvMvI3FZ2dLpE_67JWc9sQuzgFRR8g9f4ClQ31UpTW1Ste1J4EVCAtxZ-sm6EOC0QNl1DtK4DbHNACepxQ_Q/s72-c/History_Trends_Unlimited_hanxue_2019-06-29.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-7239772488186997949</id><published>2019-07-01T14:14:00.000+08:00</published><updated>2019-07-01T14:14:02.881+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Chrome"/><category scheme="http://www.blogger.com/atom/ns#" term="github"/><title type='text'>Github OpenSearch from Chrome&#39;s Omnibox</title><content type='html'>You already know it is possible to directly search from Chrome&#39;s Omnibox (address bar). For some frequently visited website, you might have noticed Chrome automatically picks up the search feature:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc67GCBE_bhrzmK1n-d3dDw0I86YmidDpiifDGrF54lkcrCg5IQWgeRztDhxXugmCQ86PADWTzv4xdjAjGOT1RxxTtmNQlBmnZf1OTUWe6Y21wVlyB-QbcXDhdnk352U3FWb82oQ/s1600/2019-06-29+Stackoverflow+Search+01.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;149&quot; data-original-width=&quot;807&quot; height=&quot;116&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc67GCBE_bhrzmK1n-d3dDw0I86YmidDpiifDGrF54lkcrCg5IQWgeRztDhxXugmCQ86PADWTzv4xdjAjGOT1RxxTtmNQlBmnZf1OTUWe6Y21wVlyB-QbcXDhdnk352U3FWb82oQ/s640/2019-06-29+Stackoverflow+Search+01.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvV1ixhWQvqfq7k54TeIsexwBi1N6VD6MG9De7RlzO7lg5XJQ-qrh8PnegP_MSC_Ahz1SKbMcHbnnvkDeOtTJdLCdzczM_f4J5TF_yle7mnrOE6_yFSTBrexWch0t-kNFnTZ7FwA/s1600/2019-06-29+Stackoverflow+Search+02.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;156&quot; data-original-width=&quot;619&quot; height=&quot;160&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvV1ixhWQvqfq7k54TeIsexwBi1N6VD6MG9De7RlzO7lg5XJQ-qrh8PnegP_MSC_Ahz1SKbMcHbnnvkDeOtTJdLCdzczM_f4J5TF_yle7mnrOE6_yFSTBrexWch0t-kNFnTZ7FwA/s640/2019-06-29+Stackoverflow+Search+02.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAfzYD1qi48RHv4xQpKme-zWpFtyq2EMIJGEP0xQEwzev4mPPqfBPyDt-C-jPsVNLVqCGIT1A4aEJ0Ct2BaKrtwJgPr88IIe51inR139uLmauJ4cqc02CIz94RyuOLqUWJXnvASw/s1600/2019-06-29+Stackoverflow+Search+03.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;310&quot; data-original-width=&quot;817&quot; height=&quot;241&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAfzYD1qi48RHv4xQpKme-zWpFtyq2EMIJGEP0xQEwzev4mPPqfBPyDt-C-jPsVNLVqCGIT1A4aEJ0Ct2BaKrtwJgPr88IIe51inR139uLmauJ4cqc02CIz94RyuOLqUWJXnvASw/s640/2019-06-29+Stackoverflow+Search+03.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;h3&gt;
OpenSearch&lt;/h3&gt;
The magic that makes this feature work is called &lt;a href=&quot;https://www.chromium.org/tab-to-search&quot;&gt;OpenSearch&lt;/a&gt;. This is StackOverflow&#39;s Open Search definition&amp;nbsp;&lt;a href=&quot;https://stackoverflow.com/opensearch.xml&quot;&gt;https://stackoverflow.com/opensearch.xml&lt;/a&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-xml&quot;&gt;&lt;code&gt;
&amp;lt;OpenSearchDescription xmlns=&quot;http://a9.com/-/spec/opensearch/1.1/&quot; xmlns:moz=&quot;http://www.mozilla.org/2006/browser/search/&quot;&amp;gt;
&amp;lt;ShortName&amp;gt;GitHub&amp;lt;/ShortName&amp;gt;
&amp;lt;Description&amp;gt;Search GitHub&amp;lt;/Description&amp;gt;
&amp;lt;InputEncoding&amp;gt;UTF-8&amp;lt;/InputEncoding&amp;gt;
&amp;lt;Image width=&quot;16&quot; height=&quot;16&quot; type=&quot;image/x-icon&quot;&amp;gt;https://github.com/favicon.ico&amp;lt;/Image&amp;gt;
&amp;lt;Url type=&quot;text/html&quot; method=&quot;get&quot; template=&quot;https://github.com/search?q={searchTerms}&amp;amp;ref=opensearch&quot;/&amp;gt;
&amp;lt;moz:SearchForm&amp;gt;https://github.com/search&amp;lt;/moz:SearchForm&amp;gt;
&amp;lt;/OpenSearchDescription&amp;gt;



&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
Github OpenSearch&lt;/h3&gt;
Github too has &lt;a href=&quot;https://github.com/opensearch.xml&quot;&gt;https://github.com/opensearch.xml&lt;/a&gt;&amp;nbsp;. But for some strange reasons Chrome is not picking it up.&lt;br /&gt;
&lt;br /&gt;
You can manually add any site&#39;s search in Chrome&#39;s settings. First, go to chrome://settings and click on &lt;b&gt;Manage Search Engine&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt; &lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjey2ghmOwmsBCAR0jifcvxVVBaGWR7oZyd9SiwP0adrNRLrD5fsm6GfrW_KsRDki94KnpwKCvHS6KEKzV68jygPHNPOy0BDFqKOC_WdITnWzLR0vWJL9v2eyO8rlHbUi55A1LtQQ/s1600/2019-06-29+Github+Search+02.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;168&quot; data-original-width=&quot;726&quot; height=&quot;148&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjey2ghmOwmsBCAR0jifcvxVVBaGWR7oZyd9SiwP0adrNRLrD5fsm6GfrW_KsRDki94KnpwKCvHS6KEKzV68jygPHNPOy0BDFqKOC_WdITnWzLR0vWJL9v2eyO8rlHbUi55A1LtQQ/s640/2019-06-29+Github+Search+02.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Chrome Manage Search Engine&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt; Click on &lt;b&gt;Add&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt; &lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdr1seKmNgqwlyBOmyMsUyCGjHsAigvvsq88pA_Clbz09M4PvELl-lIcPAiRcrp8j3UU0NK8Ran5EMaJU4xKETcocL9Uzxi0kswdhhc7yh-pRQm3Uofxvaocrm_x0LTci9RHhyow/s1600/2019-06-29+Github+Search+03.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;445&quot; data-original-width=&quot;738&quot; height=&quot;384&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdr1seKmNgqwlyBOmyMsUyCGjHsAigvvsq88pA_Clbz09M4PvELl-lIcPAiRcrp8j3UU0NK8Ran5EMaJU4xKETcocL9Uzxi0kswdhhc7yh-pRQm3Uofxvaocrm_x0LTci9RHhyow/s640/2019-06-29+Github+Search+03.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt; &lt;br /&gt;
and type in the following values:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3EstSFfb4u-MZcHX08rRa8jRdOGwo9xpMrthBpaMGEuCNyGoBwlLtC2Tewh_BxHLo9iBCiH92PME3uUsXDo7vivQS3KzkxOoUjplL1XfemyBwBiwaVPCgCRQ0MmqyJmxzy9ZhoA/s1600/2019-06-29+Github+Search+04.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;346&quot; data-original-width=&quot;509&quot; height=&quot;434&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3EstSFfb4u-MZcHX08rRa8jRdOGwo9xpMrthBpaMGEuCNyGoBwlLtC2Tewh_BxHLo9iBCiH92PME3uUsXDo7vivQS3KzkxOoUjplL1XfemyBwBiwaVPCgCRQ0MmqyJmxzy9ZhoA/s640/2019-06-29+Github+Search+04.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Search Engine: &lt;b&gt;Github&lt;/b&gt;&lt;br /&gt;
Keyword: &lt;b&gt;gh&lt;/b&gt;&lt;br /&gt;
URL:&amp;nbsp;&lt;b&gt;https://github.com/search?q=%s&amp;amp;ref=opensearch&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
You can use any keyword you preferred. I used &lt;kbd&gt;g&lt;/kbd&gt; for Google, so I am using &lt;kbd&gt;gh&lt;/kbd&gt; for Github.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Searching&lt;/h3&gt;
After adding the shortcut, you can enter &lt;kbd&gt;gh&lt;/kbd&gt; in the omnibox and directly search Github&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW7X-tmjJd17PWrPAVwyF7Luh6U6iuMZ2wTh1T1Ej1iputr2qP6m54pRCuI0V1i5Qq7ZZ2oGAvIS1khZTLgVOb1PkSdiavDNEwTezS5JcUUGdkXms3i2phEWz0rtU56h2lUuW3ng/s1600/2019-06-29+Github+Search+05.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;149&quot; data-original-width=&quot;450&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW7X-tmjJd17PWrPAVwyF7Luh6U6iuMZ2wTh1T1Ej1iputr2qP6m54pRCuI0V1i5Qq7ZZ2oGAvIS1khZTLgVOb1PkSdiavDNEwTezS5JcUUGdkXms3i2phEWz0rtU56h2lUuW3ng/s1600/2019-06-29+Github+Search+05.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8DzhZS0nAL6lDFFjbbZgudmEYsQ0cQn4IzvAjp2lT9bbI09Gny57CxMo3MN1vslSNvYk7DVquCm_OMSQGPzo3BAj1zrLEJizY_My8MXh4nb9W7bjkg31gvQR-OHUpCzhJMMoo-g/s1600/2019-06-29+Github+Search+06.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;282&quot; data-original-width=&quot;836&quot; height=&quot;214&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8DzhZS0nAL6lDFFjbbZgudmEYsQ0cQn4IzvAjp2lT9bbI09Gny57CxMo3MN1vslSNvYk7DVquCm_OMSQGPzo3BAj1zrLEJizY_My8MXh4nb9W7bjkg31gvQR-OHUpCzhJMMoo-g/s640/2019-06-29+Github+Search+06.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/7239772488186997949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/7239772488186997949' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/7239772488186997949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/7239772488186997949'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/07/github-opensearch-from-chromes-omnibox.html' title='Github OpenSearch from Chrome&#39;s Omnibox'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhc67GCBE_bhrzmK1n-d3dDw0I86YmidDpiifDGrF54lkcrCg5IQWgeRztDhxXugmCQ86PADWTzv4xdjAjGOT1RxxTtmNQlBmnZf1OTUWe6Y21wVlyB-QbcXDhdnk352U3FWb82oQ/s72-c/2019-06-29+Stackoverflow+Search+01.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-3571932667465679158</id><published>2019-06-25T12:27:00.001+08:00</published><updated>2019-06-25T12:28:11.687+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ImageMagick"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><title type='text'>How to convert multi-page PDF to images in command line</title><content type='html'>&lt;a href=&quot;https://en.wikipedia.org/wiki/Ghostscript&quot;&gt;Ghostscript &lt;/a&gt;is your best bet to convert PDF (or PS files) into image formats. But the command is not as user-friendly:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
gswin64c.exe -dNOPAUSE -sDEVICE=jpeg -r200 -dJPEGQ=60 -sOutputFile=document-%02d.jpg document.pdf -dBATCH


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Compare to the equivalent in ImageMagick&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
magick -quality 60 -density 200 document.pdf document-%02d.jpg


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
You do need to have Ghostscript installed, &lt;a href=&quot;https://flummox-engineering.blogspot.com/2019/06/imagemagick-FailedToExecuteCommand-gswin64c.exe-gswin32c.exe.html&quot;&gt;or else you will see this error message&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Image Quality&lt;/h3&gt;Note that even if you use &lt;kbd&gt;-quality 100&lt;/kbd&gt; you may still get low quality image output. Unlike images, PDF files do not have a native resolution or scale. After all, they are documents meant for printing, so dots per inch (dpi) is the unit of measurement for resolution.&amp;nbsp;This density and other settings such as colorspace will impact the quality of output. You can specify them in the input:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
magick -density 300 -colorspace sRGB input.pdf output.jpg


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Specifically if you need to convert CMYK PDF into RGB PNG or JPEG, you will need to edit &lt;kbd&gt;delegates.xml&lt;/kbd&gt; inside ImageMagick&#39;s directory and add the &lt;kbd&gt;-dUseCIEColor=false&lt;/kbd&gt; option for &lt;kbd&gt;delegate decode=&quot;ps:cmyk&quot;&lt;/kbd&gt;, so it will look like:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-xml&quot;&gt;&lt;code&gt;
&amp;lt;delegate decode=&quot;ps:cmyk&quot; restrain=&quot;True&quot; command=&quot;&amp;amp;quot;@PSDelegate@&amp;amp;quot; -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dEPSCrop -dAlignToPixels=0 -dGridFitTT=2 &amp;amp;quot;-sDEVICE=pamcmyk32&amp;amp;quot; -dTextAlphaBits=%u -dGraphicsAlphaBits=%u &amp;amp;quot;-r%s&amp;amp;quot; %s &amp;amp;quot;-sOutputFile=%s&amp;amp;quot; -dUseCIEColor=false &amp;amp;quot;-f%s&amp;amp;quot; &amp;amp;quot;-f%s&amp;amp;quot;&quot;/&amp;gt;


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;a href=&quot;https://stackoverflow.com/a/20008627/399759&quot;&gt;Answer on StackOverflo&lt;/a&gt;w by&amp;nbsp;&lt;a href=&quot;https://stackoverflow.com/users/2846289/user2846289&quot;&gt;user2846289&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;If you are sure about the output size, you can also &lt;kbd&gt;-scale&lt;/kbd&gt; it&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
magick -density 300 -scale 800 input.pdf output.jpg


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Some PDF files also have transparency - and the transparent region will turn into black background. You can &lt;kbd&gt;-flatten&lt;/kbd&gt; the image so that it has a white background, like what you see on screen.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
magick -density 300 -flatten input.pdf output.jpg


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;You can also limit the JPEG output size&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
magick -density 200 input.pdf -define jpeg:extent=300kb output-%02d.jpg


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Combine Into Single Image&lt;/h3&gt;&lt;div&gt;By default, each PDF page will be output into individual image file. You can combine all the images into a single file with the &lt;kbd&gt;-append&lt;/kbd&gt; option&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
magick -density 200 document.pdf -append single-document.jpg


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Note: the &lt;kbd&gt;magick.exe&lt;/kbd&gt; executable is usually installed as &lt;kbd&gt;convert&lt;/kbd&gt; in Linux and MacOS.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm_DLmsZ6kAFBel834CPXFJO1oGUoLev8bLSm9j_VDbXjQObu7GT5SVzZ6md8CSg0Dr9cEPpZTC1xVyCUAwOQRHHIhs2sgqYC0yG3o1JGZE9Sfyh7Mn2kdiK9hadYkJEmWaEk8yA/s1600/ImageMagick_logo.svg.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1242&quot; data-original-width=&quot;1200&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm_DLmsZ6kAFBel834CPXFJO1oGUoLev8bLSm9j_VDbXjQObu7GT5SVzZ6md8CSg0Dr9cEPpZTC1xVyCUAwOQRHHIhs2sgqYC0yG3o1JGZE9Sfyh7Mn2kdiK9hadYkJEmWaEk8yA/s320/ImageMagick_logo.svg.png&quot; width=&quot;309&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/3571932667465679158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/3571932667465679158' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/3571932667465679158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/3571932667465679158'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/06/how-to-convert-multi-page-pdf-to-images-in-command-line.html' title='How to convert multi-page PDF to images in command line'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm_DLmsZ6kAFBel834CPXFJO1oGUoLev8bLSm9j_VDbXjQObu7GT5SVzZ6md8CSg0Dr9cEPpZTC1xVyCUAwOQRHHIhs2sgqYC0yG3o1JGZE9Sfyh7Mn2kdiK9hadYkJEmWaEk8yA/s72-c/ImageMagick_logo.svg.png" height="72" width="72"/><thr:total>1</thr:total><georss:featurename>Wudaokou, Haidian, Beijing, China</georss:featurename><georss:point>39.992419 116.33937000000003</georss:point><georss:box>39.9680885 116.29902950000003 40.016749499999996 116.37971050000003</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-2325370172535155189</id><published>2019-04-10T23:38:00.001+08:00</published><updated>2019-04-10T23:38:11.129+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><title type='text'>When to use xargs and exec</title><content type='html'>In a recent post, I have written about &lt;a href=&quot;https://hanxue-it.blogspot.com/2019/04/how-to-find-and-open-files-using-bash-on-vscode-visual-studio-code.html&quot;&gt;searching for files using &lt;b&gt;find&lt;/b&gt;&amp;nbsp;and opening them using Visual Studio Code&lt;/a&gt;. But what is the difference between &lt;kbd&gt;xargs&lt;/kbd&gt; and &lt;kbd&gt;find . [args] -exec [cmd] {} \;&lt;/kbd&gt;? Why can&#39;t we just pipe it?&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Using Pipes&lt;/h3&gt;
Using pipes is one of the most natural thing to do in UNIX. So why can&#39;t we simply pipe the output to &lt;kbd&gt;code&lt;/kbd&gt;?&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettify lang-sh&quot;&gt;&lt;code&gt;
$ find . -name xcode_requirement* | code
Run with &#39;code -&#39; to read from stdin (e.g. &#39;ps aux | grep code | code -&#39;).


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The command above does not work because we are passing the filenames as &lt;kbd&gt;STDIN&lt;/kbd&gt; to the &lt;kbd&gt;code&lt;/kbd&gt; command. We are not passing &lt;i&gt;arguments&lt;/i&gt;&amp;nbsp;to the &lt;kbd&gt;code&lt;/kbd&gt; command line, but we are simply passing a chunk of text.&lt;br /&gt;
&lt;br /&gt;
Note that pipe simply transfer the standard output &lt;kbd&gt;STDOUT&lt;/kbd&gt; of the preceding command (to the left of the pipe) as the standard input &lt;kbd&gt;STDIN&lt;/kbd&gt; of the following (to the right of the pipe) command.&lt;br /&gt;
&lt;br /&gt;
This article covers a simple example, searching for a list of files and opening those files with another application. But if you are chaining pipes and running more complicated commands, note that&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
UNIX pipes does not guarantee the execution order of processes.&amp;nbsp;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Difference between xargs and exec&lt;/h3&gt;
OK, so we cannot rely on STDIN, and need to pass a list of arguments &lt;kbd&gt;argv&lt;/kbd&gt; to the command. But what is the difference between&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettify lang-sh&quot;&gt;&lt;code&gt;
find . -name &quot;*.rb&quot; -exec code {} \+


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
and&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettify lang-sh&quot;&gt;&lt;code&gt;
find . -name &quot;*.rb&quot; | xargs code


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
?&lt;br /&gt;
&lt;br /&gt;
The difference is that &lt;kbd&gt;xargs&lt;/kbd&gt; will stop execution if the &lt;kbd&gt;code&lt;/kbd&gt; sub-command fails, whereas even if &lt;kbd&gt;code&lt;/kbd&gt; fails on one of the files, &lt;kbd&gt;find&lt;/kbd&gt; will continue passing the next file. In short, &lt;kbd&gt;find -exec&lt;/kbd&gt; returns the exit code of itself, but &lt;kbd&gt;xargs&lt;/kbd&gt; will return the exit code of the sub-command.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Performance&lt;/h3&gt;
&lt;a href=&quot;https://www.everythingcli.org/find-exec-vs-find-xargs/&quot;&gt;This article went into the detail of the performance&lt;/a&gt; of &lt;kbd&gt;find -exec&lt;/kbd&gt; vs &lt;kbd&gt;xargs&lt;/kbd&gt;. This is the summary of the result&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVaI2bcahbQhRBES59j19hU03gTgVz7LW3gUqieTvy4mJSYnrVvt0E4iN-ThthrUmqP0jnVxHJTg8v_cvLYuVjaftfu094KTz_fL-kSuma7yhuy4T8NJqzP1UttUtC48GSUu8F-g/s1600/find-vs-xargs.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;338&quot; data-original-width=&quot;502&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVaI2bcahbQhRBES59j19hU03gTgVz7LW3gUqieTvy4mJSYnrVvt0E4iN-ThthrUmqP0jnVxHJTg8v_cvLYuVjaftfu094KTz_fL-kSuma7yhuy4T8NJqzP1UttUtC48GSUu8F-g/s1600/find-vs-xargs.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&amp;nbsp;In summary&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;use &lt;kbd&gt;xargs&lt;/kbd&gt; if you have to pipe the input, otherwise&lt;/li&gt;
&lt;li&gt;use &lt;kbd&gt;find . [args] -exec [sub-command] {} \+&lt;/kbd&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/2325370172535155189/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/2325370172535155189' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2325370172535155189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2325370172535155189'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/04/when-to-use-xargs-and-exec.html' title='When to use xargs and exec'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVaI2bcahbQhRBES59j19hU03gTgVz7LW3gUqieTvy4mJSYnrVvt0E4iN-ThthrUmqP0jnVxHJTg8v_cvLYuVjaftfu094KTz_fL-kSuma7yhuy4T8NJqzP1UttUtC48GSUu8F-g/s72-c/find-vs-xargs.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-6420846620383295748</id><published>2019-04-10T18:16:00.001+08:00</published><updated>2019-04-10T22:19:13.115+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="vscode"/><title type='text'>How to Find and Open Files on Visual Studio Code</title><content type='html'>Visual Studio Code has an excellent interface and File Explorer. Use Quick Open with &lt;kbd&gt;⌘&lt;/kbd&gt; + &lt;kbd&gt;P&lt;/kbd&gt; or &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;P&lt;/kbd&gt; and type in the file name. But what if you want to search through a complex project and find files with a specific pattern? Sometimes it is easier to just use simple bash commands with regex.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Opening A Single File&lt;/h3&gt;Search for the filename and then pipe it through &lt;b&gt;code&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ find . -name &quot;xcode_requirement*&quot; | xargs code


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Technically, a more efficient way to open a single file is to run it through use &lt;b&gt;exec&lt;/b&gt;. It&#39;s just more keystrokes.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ find . -name &quot;xcode_requirement.*&quot; -exec code {} \;


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Or you could just create a sub-shell&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ code &quot;$(find . -name xcode_requirement.rb)&quot;


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;Opening Multiple Files&lt;/h3&gt;Search and opening multiple files is a bit different. Do you want to open all the files in a &lt;b&gt;new window&lt;/b&gt;? If so, use a sub-shell&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ code &quot;$(find . -name *.rb)&quot;


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0UvP97ubzrL-U_5OG1DBVP3ZdoNdtJDIpW2ar0r1xDYfaLkfKBM2E2iAHD2x3gFHXvIoqpv8lv_V8KxJQT5b0WHHxywYuLRRz_0AZ1IlBfnOM2MIEfNsUIBdsRTzakDOMlYvyqA/s1600/vscode_subshell.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;351&quot; data-original-width=&quot;715&quot; height=&quot;314&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0UvP97ubzrL-U_5OG1DBVP3ZdoNdtJDIpW2ar0r1xDYfaLkfKBM2E2iAHD2x3gFHXvIoqpv8lv_V8KxJQT5b0WHHxywYuLRRz_0AZ1IlBfnOM2MIEfNsUIBdsRTzakDOMlYvyqA/s640/vscode_subshell.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Opening a list of searched files in a new window&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;But if you want to open all the files in an existing window, use &lt;b&gt;xargs&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ find . -name &quot;*.rb&quot; | xargs code


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;You can also use &lt;b&gt;find&lt;/b&gt;, but use &quot;\+&quot; so that all the results are concatenated in one line, and &lt;b&gt;code&lt;/b&gt;&amp;nbsp;is only invoked once, instead of every time for each result.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ find . -name &quot;*.rb&quot; -exec code {} \+


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVDlcg6tsB_0LkNNRM63v_7mCNk1ToYWzORcqtjDrKAjTAkaBF_qxmiKbREe8TEUpQl8Non0A2Gkd_WwJaQFyys93nZXhoLDSpgoZFi_2thsJOuodHtTQ638eJjkhX4pldBPA9Tg/s1600/vscode-existing-window.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;311&quot; data-original-width=&quot;755&quot; height=&quot;262&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVDlcg6tsB_0LkNNRM63v_7mCNk1ToYWzORcqtjDrKAjTAkaBF_qxmiKbREe8TEUpQl8Non0A2Gkd_WwJaQFyys93nZXhoLDSpgoZFi_2thsJOuodHtTQ638eJjkhX4pldBPA9Tg/s640/vscode-existing-window.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;font-size: 12.8px;&quot;&gt;Opening a list of searched files in the existing window&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;br style=&quot;font-size: medium; text-align: start;&quot; /&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Opening with Other Applications&lt;/h3&gt;&lt;div&gt;The commands above also can be used with other applications. If you want to open the file(s) with the default registered application (&lt;b&gt;open&lt;/b&gt;&amp;nbsp;in MacOS / &lt;b&gt;xdg-open&lt;/b&gt;&amp;nbsp;in Linux / &lt;b&gt;start&lt;/b&gt;&amp;nbsp;in Windows), simply substitute the command&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ find . -name &quot;xcode_requirement*&quot; | xargs open


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/6420846620383295748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/6420846620383295748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/6420846620383295748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/6420846620383295748'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/04/how-to-find-and-open-files-using-bash-on-vscode-visual-studio-code.html' title='How to Find and Open Files on Visual Studio Code'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0UvP97ubzrL-U_5OG1DBVP3ZdoNdtJDIpW2ar0r1xDYfaLkfKBM2E2iAHD2x3gFHXvIoqpv8lv_V8KxJQT5b0WHHxywYuLRRz_0AZ1IlBfnOM2MIEfNsUIBdsRTzakDOMlYvyqA/s72-c/vscode_subshell.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-3516014049114590125</id><published>2019-01-20T10:00:00.000+08:00</published><updated>2019-01-20T10:00:04.266+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="docker"/><title type='text'>Migrating Docker Machine to external hard disk</title><content type='html'>This article will show you how to move Docker Machine VM image to another location. I have a small SSD disk as my built in hard disk, and had to move my Docker Machine&#39;s VM to an external USB hard disk.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Move the Docker Machine image&lt;/h3&gt;
Before making any changes, stop any instances of docker machine.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ docker-machine stop
Stopping &quot;default&quot;...
Machine &quot;default&quot; is already stopped.


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Move the entire &lt;kbd&gt;~/.docker/machine/&lt;/kbd&gt; directory. You will need to tell Docker Machine the new path to the VM. Consider adding the &lt;kbd&gt;MACHINE_STORAGE_PATH&lt;/kbd&gt; environment variable to your &lt;kbd&gt;./bashrc&lt;/kbd&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ mv ~/.docker/machine /Volumes/USB/docker/
$ export MACHINE_STORAGE_PATH=/Volumes/USB/docker/machine/


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
Update VirtualBox VM location&lt;/h3&gt;
Docker Machine knows where to look for the files, but we also need to tell the VM hypervisor of the location. If you are using the default VirtualBox VM driver, open up the VirtualBox application&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1YvTTdnSh11tz-nnJ43KkUHikPvnf0hCWcPaSwDPQSkAcbJiR38kB_o2vk2nOF1y6swVoPbtqScw8K3vk4dYJDOuytxjnh4RqzzHGD0AQes9C3BTvYtrKbarrn7Lk_TraqYz6-g/s1600/virtualbox-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;301&quot; data-original-width=&quot;809&quot; height=&quot;148&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1YvTTdnSh11tz-nnJ43KkUHikPvnf0hCWcPaSwDPQSkAcbJiR38kB_o2vk2nOF1y6swVoPbtqScw8K3vk4dYJDOuytxjnh4RqzzHGD0AQes9C3BTvYtrKbarrn7Lk_TraqYz6-g/s400/virtualbox-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;VirtualBox showing the VM is now inaccessible&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
VirtualBox will complain that the VM is inaccessible and you will see an error message similar to this&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ docker-machine -s /Volumes/USB/docker/machine start
Starting &quot;default&quot;...
(default) Check network to re-create if needed...
Unable to start the VM: /usr/local/bin/VBoxManage startvm default --type headless failed:
VBoxManage: error: Could not open the medium &#39;/Users/hanxue/.docker/machine/machines/default/disk.vmdk&#39;.
VBoxManage: error: VD: error VERR_FILE_NOT_FOUND opening image file &#39;/Users/hanxue/.docker/machine/machines/default/disk.vmdk&#39; (VERR_FILE_NOT_FOUND)
VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component MediumWrap, interface IMedium


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Remove&lt;/b&gt; the Virtual Machine. Then go to &lt;kbd&gt;Machine&lt;/kbd&gt; ➜ &lt;kbd&gt;Add...&lt;/kbd&gt; and browse to the new location and open &lt;kbd&gt;default.vbox&lt;/kbd&gt;.&lt;br /&gt;
&lt;br /&gt;
We are not done yet - we need to tell VirtualBox about the updated disk images. Open up the &lt;b&gt;Settings&lt;/b&gt;&amp;nbsp;of the &lt;b&gt;default&lt;/b&gt;&amp;nbsp;VM, and click on &lt;b&gt;Storage&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCZ0g24Oub50VV1nPlQDirccbGCGXrzSguBsqjLpu7VmqCcuL4Z2piZ_RMANl2KL73dORI-VVEeEFqTdV3kRhM7HtdV1ToovkKdjMpSU4_xX6tMlzjbTzTB_igNX4iGzBxe0vnYQ/s1600/virtualbox-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;544&quot; data-original-width=&quot;651&quot; height=&quot;333&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCZ0g24Oub50VV1nPlQDirccbGCGXrzSguBsqjLpu7VmqCcuL4Z2piZ_RMANl2KL73dORI-VVEeEFqTdV3kRhM7HtdV1ToovkKdjMpSU4_xX6tMlzjbTzTB_igNX4iGzBxe0vnYQ/s400/virtualbox-3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;VirtualBox VM with invalid storage devices&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
You will need to remove both the disk images and re-add them. &lt;kbd&gt;boot2docker.iso&lt;/kbd&gt; is an Optical drive and &lt;kbd&gt;disk.vmdk&lt;/kbd&gt; is a disk image.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh49lVaChZQZKqCrGCUX9q8QUZl_rYb0Hz-ai61bDPf49rTL-ryGKJWWFCbThdxa2o0ErxFyGcdur1x6RqW8yl32HHkUCcdVsbfk5cWXCtfDKZpix-nUY999gRIrB0Q60nmfbQHsA/s1600/virtualbox-4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;544&quot; data-original-width=&quot;651&quot; height=&quot;333&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh49lVaChZQZKqCrGCUX9q8QUZl_rYb0Hz-ai61bDPf49rTL-ryGKJWWFCbThdxa2o0ErxFyGcdur1x6RqW8yl32HHkUCcdVsbfk5cWXCtfDKZpix-nUY999gRIrB0Q60nmfbQHsA/s400/virtualbox-4.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Disk images re-added&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div&gt;
Remember to set the shell environment variable &lt;kbd&gt;MACHINE_STORAGE_PATH&lt;/kbd&gt; or else docker-machine will complain the VM is missing.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ docker-machine start
Error: No machine name(s) specified and no &quot;default&quot; machine exists


&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Alternatively, you can use &lt;kbd&gt;-s&lt;/kbd&gt; to specify the storage for the docker machine.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ docker-machine -s /Volumes/USB/docker/machine start


&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwX_jlf3WfkETj7xhPf6AQr7SpQY89MMYbY2jOx3RIdUIyw1cZOboEjqeQW6wFmL10lKql_l_rpZukwflfjnFn7Cx4EvXUmREQjOcxDoALhnWZEQuRBUFFa89eOhOgeDlL7umWHw/s1600/Docker_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;60&quot; data-original-width=&quot;250&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwX_jlf3WfkETj7xhPf6AQr7SpQY89MMYbY2jOx3RIdUIyw1cZOboEjqeQW6wFmL10lKql_l_rpZukwflfjnFn7Cx4EvXUmREQjOcxDoALhnWZEQuRBUFFa89eOhOgeDlL7umWHw/s1600/Docker_logo.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Docker logo&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/3516014049114590125/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/3516014049114590125' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/3516014049114590125'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/3516014049114590125'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/migrating-docker-machine-to-external.html' title='Migrating Docker Machine to external hard disk'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1YvTTdnSh11tz-nnJ43KkUHikPvnf0hCWcPaSwDPQSkAcbJiR38kB_o2vk2nOF1y6swVoPbtqScw8K3vk4dYJDOuytxjnh4RqzzHGD0AQes9C3BTvYtrKbarrn7Lk_TraqYz6-g/s72-c/virtualbox-1.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-9182461531142825093</id><published>2019-01-19T08:00:00.000+08:00</published><updated>2019-01-21T02:24:29.143+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Blogger"/><category scheme="http://www.blogger.com/atom/ns#" term="Facebook"/><title type='text'>How to Get Facebook to Show Featured Image from Blogger Homepage</title><content type='html'>In my earlier post, I have shown how to set the featured image when sharing your blog&#39;s homepage on Twitter.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7rwIU53TSHoqz36s63UXmyXJPYDKGNmCwbQgWpq9SBkSYVw_IePrf3fZb-IxvlYDbgfGlPRji_u8N-ic1mbW4usvOMN-YNsS9EAS96srAC_0vf3onBrREjxVfxn-WUqXgk_s76w/s1600/facebook-preview02.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;244&quot; data-original-width=&quot;529&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7rwIU53TSHoqz36s63UXmyXJPYDKGNmCwbQgWpq9SBkSYVw_IePrf3fZb-IxvlYDbgfGlPRji_u8N-ic1mbW4usvOMN-YNsS9EAS96srAC_0vf3onBrREjxVfxn-WUqXgk_s76w/s1600/facebook-preview02.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Twitter image preview of blog homepage&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When I share this blog&#39;s homepage on Facebook, I get to see this irrelevant photo instead&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVa2IlXo52NbKzFsvAwjaZW9qdZiLzBFTX-Zzik6OcT2ZDqTg7jWTgo__MvMtYaOijtQoK4DtPgyIqsc4VU2ijXNXb8KaBao4mVeV1t6nl0ODe9QM8n7RPaF2OmcSprZ0Qikk6xA/s1600/facebook-feature-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;428&quot; data-original-width=&quot;500&quot; height=&quot;341&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVa2IlXo52NbKzFsvAwjaZW9qdZiLzBFTX-Zzik6OcT2ZDqTg7jWTgo__MvMtYaOijtQoK4DtPgyIqsc4VU2ijXNXb8KaBao4mVeV1t6nl0ODe9QM8n7RPaF2OmcSprZ0Qikk6xA/s400/facebook-feature-1.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Facebook share without featured image&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Featured Image&lt;/h3&gt;First, decide on the featured image that you want to use. I will be using this image, the same as Twitter&#39;s image for this blog&#39;s homepage&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwtKF4VIiNfjAZxlxL-Z-b7x1XgzhzzehAZH0_YwwSBIUqUi3xg2N7D63ry356dSPHQ2QxyHZXRrkSX_y_atOoCU9yJkpgyC_qvRBYOvM6RDIcOyc9D7VmJhfYpX6ZAGlimtJC4A/s1600/Screen+Shot+2014-06-25+at+2.14.03+PM.png


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Facebook recommends the image dimension to be &lt;b&gt;1200x630&lt;/b&gt;, so let&#39;s get that size from Blogger / Google Photo&#39;s responsive image. Change the &lt;kbd&gt;s1600&lt;/kbd&gt; parameter to &lt;kbd&gt;w1200-h630-p-nu&lt;/kbd&gt; which is set to 1200 x 630, with smart crop and no upscale&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwtKF4VIiNfjAZxlxL-Z-b7x1XgzhzzehAZH0_YwwSBIUqUi3xg2N7D63ry356dSPHQ2QxyHZXRrkSX_y_atOoCU9yJkpgyC_qvRBYOvM6RDIcOyc9D7VmJhfYpX6ZAGlimtJC4A/w1200-h630-p-nu/Screen+Shot+2014-06-25+at+2.14.03+PM.png


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
To set the Featured Image, open up your Blogger&#39;s template and &lt;kbd&gt;Edit HTML&lt;/kbd&gt;, search for&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
&amp;lt;b:include data=&#39;blog&#39; name=&#39;all-head-content&#39;/&amp;gt;


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
My previous post has covered showing the preview images in a Twitter card when sharing the blog home page. Look for the &lt;kbd&gt;data:blog.postImageUrl&lt;/kbd&gt; condition, and add image URL for &lt;kbd&gt;og:title&lt;/kbd&gt;. This is how it looks&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;b:if cond=&#39;data:blog.postImageUrl&#39;&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta expr:content=&#39;data:blog.postImageUrl&#39; name=&#39;twitter:image&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta expr:content=&#39;data:blog.postImageUrl&#39; name=&#39;og:image&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;b:else/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta content=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwtKF4VIiNfjAZxlxL-Z-b7x1XgzhzzehAZH0_YwwSBIUqUi3xg2N7D63ry356dSPHQ2QxyHZXRrkSX_y_atOoCU9yJkpgyC_qvRBYOvM6RDIcOyc9D7VmJhfYpX6ZAGlimtJC4A/s1600/Screen+Shot+2014-06-25+at+2.14.03+PM.png&#39; name=&#39;twitter:image&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta content=&#39;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwtKF4VIiNfjAZxlxL-Z-b7x1XgzhzzehAZH0_YwwSBIUqUi3xg2N7D63ry356dSPHQ2QxyHZXRrkSX_y_atOoCU9yJkpgyC_qvRBYOvM6RDIcOyc9D7VmJhfYpX6ZAGlimtJC4A/s1600/Screen+Shot+2014-06-25+at+2.14.03+PM.png&#39; name=&#39;og:image&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/b:if&amp;gt;


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYWrNxS9u4pPRwU9LoW4QXgtCbXuPKIogx0H2VZ87PM50lnFwzs_Y5DT5YfxmUz3KxotPVy-tKzc0NO__wQYZAK_h1CIeig4Osg1V-YJUSa29rIwQEAxyJcozj7tA3tFqChZ4m1A/s1600/facebook-preview-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;364&quot; data-original-width=&quot;1065&quot; height=&quot;218&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYWrNxS9u4pPRwU9LoW4QXgtCbXuPKIogx0H2VZ87PM50lnFwzs_Y5DT5YfxmUz3KxotPVy-tKzc0NO__wQYZAK_h1CIeig4Osg1V-YJUSa29rIwQEAxyJcozj7tA3tFqChZ4m1A/s640/facebook-preview-3.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Adding the Blogger featured image for Facebook using the &quot;og:image&quot; Open Graph tag&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
You can check if sharing on Facebook works correctly using the &lt;a href=&quot;https://developers.facebook.com/tools/debug/og/object/&quot;&gt;Facebook Open Graph Object Debugger&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_bdJrdahpxuzsDqmpJO7t7YB979osyAJ3rPFGxNFSVcQToK3OEXbTxe42gdCNBhaNEHxe44L5Z29AQKtNvc8GYQ4mMCmiswI_AUMH5THrQ-t0rl_xinh4KaGxvgvTauIGBCWflg/s1600/facebook-preview-4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;664&quot; data-original-width=&quot;1264&quot; height=&quot;336&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_bdJrdahpxuzsDqmpJO7t7YB979osyAJ3rPFGxNFSVcQToK3OEXbTxe42gdCNBhaNEHxe44L5Z29AQKtNvc8GYQ4mMCmiswI_AUMH5THrQ-t0rl_xinh4KaGxvgvTauIGBCWflg/s640/facebook-preview-4.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Preview of your Blogger homepage when shared on Facebook&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/9182461531142825093/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/9182461531142825093' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/9182461531142825093'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/9182461531142825093'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/how-to-get-facebook-to-show-featured.html' title='How to Get Facebook to Show Featured Image from Blogger Homepage'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7rwIU53TSHoqz36s63UXmyXJPYDKGNmCwbQgWpq9SBkSYVw_IePrf3fZb-IxvlYDbgfGlPRji_u8N-ic1mbW4usvOMN-YNsS9EAS96srAC_0vf3onBrREjxVfxn-WUqXgk_s76w/s72-c/facebook-preview02.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-220380487008020842</id><published>2019-01-18T22:30:00.000+08:00</published><updated>2019-01-21T02:26:39.358+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Blogger"/><category scheme="http://www.blogger.com/atom/ns#" term="Facebook"/><title type='text'>Show an Image Preview When Sharing a Blogger Post to Facebook</title><content type='html'>When you share a link from a popular website on Facebook, you will see a nice image preview, and some description of the article.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlWPEZHVKutihzOcyd3qEI1QvHPKfeJXuPxZscwyYy03ZqdzpetR2XJftAUdg8Gac8ZHvQtkVcsN6XJmNmbxViq27aOrAPWv2Y3xKMjGlGfwIWiYU9HhS-aKn9Jug24oxeISzxHA/s1600/facebook-link-with-preview.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;544&quot; data-original-width=&quot;515&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlWPEZHVKutihzOcyd3qEI1QvHPKfeJXuPxZscwyYy03ZqdzpetR2XJftAUdg8Gac8ZHvQtkVcsN6XJmNmbxViq27aOrAPWv2Y3xKMjGlGfwIWiYU9HhS-aKn9Jug24oxeISzxHA/s1600/facebook-link-with-preview.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Sharing a Foreign Policy article on Facebook&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
But when you share your blog article on Facebook, it will appear as a simple link. No images, no title and description. Hmm... very compelling to click and read the article right?&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimL2FspgRdhDDchu2F0f2OLGtUzT_xE34YgtTL5_4xkNoJVKdbyCFpIdZ3sUD3y8S0mhC6vFZ_SdZMQkN3ZAu2zOFyomnBk9sB9hJz_88ykoXfOItvJqvMBoULSiF7wf9osRiShg/s1600/facebook-no-preview.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;178&quot; data-original-width=&quot;512&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimL2FspgRdhDDchu2F0f2OLGtUzT_xE34YgtTL5_4xkNoJVKdbyCFpIdZ3sUD3y8S0mhC6vFZ_SdZMQkN3ZAu2zOFyomnBk9sB9hJz_88ykoXfOItvJqvMBoULSiF7wf9osRiShg/s1600/facebook-no-preview.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Sharing Blogger link on Facebook without preview&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;h3&gt;Open Graph Sharing&lt;/h3&gt;Facebook created Open Graph sharing to facilitate sharing rich media content from around the Internet. You can &lt;a href=&quot;https://developers.facebook.com/docs/sharing/webmasters/&quot;&gt;read more about it and see examples here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
We need to tell Blogger to generate these Open Graph tags for all the articles that we publish. Open up your Blogger settings and navigate to &lt;kbd&gt;Theme&lt;/kbd&gt; → &lt;kbd&gt;Edit HTML&lt;/kbd&gt; and scroll up to the beginning with the &lt;kbd&gt;html&lt;/kbd&gt; tag where the namespaces are defined. Add the Open Graph namespace at end of the HTML tag &lt;kbd&gt;xmlns:og=&#39;http://ogp.me/ns#&#39;&lt;/kbd&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&amp;gt;

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html b:render=&#39;false&#39; b:version=&#39;2&#39; class=&#39;v2&#39; expr:dir=&#39;data:blog.languageDirection&#39; xmlns=&#39;http://www.w3.org/1999/xhtml&#39; xmlns:b=&#39;http://www.google.com/2005/gml/b&#39; xmlns:data=&#39;http://www.google.com/2005/gml/data&#39; xmlns:expr=&#39;http://www.google.com/2005/gml/expr&#39; xmlns:og=&#39;http://ogp.me/ns#&#39;&amp;gt;


&lt;/code&gt;&lt;/pre&gt;Next, scroll down to just before the closing tag of &lt;kbd&gt;&amp;amp;lt;/head&amp;amp;gt;&lt;/kbd&gt; and add in these open graph tags&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
&amp;lt;!-- Open Graph Meta Tags BEGIN --&amp;gt;
&amp;lt;meta expr:content=&#39;data:blog.pageName&#39; property=&#39;og:title&#39;/&amp;gt;
&amp;lt;b:if cond=&#39;data:blog.postImageThumbnailUrl&#39;&amp;gt;
  &amp;lt;meta expr:content=&#39;data:blog.postImageThumbnailUrl&#39; property=&#39;og:image&#39;/&amp;gt;
&amp;lt;/b:if&amp;gt;
&amp;lt;meta expr:content=&#39;data:blog.title&#39; property=&#39;og:title&#39;/&amp;gt;
&amp;lt;meta expr:content=&#39;data:blog.canonicalUrl&#39; property=&#39;og:url&#39;/&amp;gt;
&amp;lt;b:if cond=&#39;data:blog.metaDescription&#39;&amp;gt;
  &amp;lt;meta expr:content=&#39;data:blog.metaDescription&#39; property=&#39;og:description&#39;/&amp;gt;
&amp;lt;/b:if&amp;gt;
&amp;lt;!-- Open Graph Meta Tags END --&amp;gt;
&amp;lt;/head&amp;gt;

&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
When you share your link, Facebook will look for the article&#39;s title and get a description from your article, and include the image found in your article.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYbrboSRs947hEReAikIs43ISeucEDobCEE4Kg94on989TpyCDz3tFZxC1insZ3JDmf7pXFr-J0bjkPWGLAtTooH3P05zmuiiwYGuRYk-DF5QsgsvygkWuhBi1mLb1nSdtrRPlnw/s1600/facebook-with-preview.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;466&quot; data-original-width=&quot;500&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhYbrboSRs947hEReAikIs43ISeucEDobCEE4Kg94on989TpyCDz3tFZxC1insZ3JDmf7pXFr-J0bjkPWGLAtTooH3P05zmuiiwYGuRYk-DF5QsgsvygkWuhBi1mLb1nSdtrRPlnw/s1600/facebook-with-preview.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Now Facebook will show a preview from your Blogger link&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/220380487008020842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/220380487008020842' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/220380487008020842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/220380487008020842'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/show-image-preview-when-sharing-blogger.html' title='Show an Image Preview When Sharing a Blogger Post to Facebook'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlWPEZHVKutihzOcyd3qEI1QvHPKfeJXuPxZscwyYy03ZqdzpetR2XJftAUdg8Gac8ZHvQtkVcsN6XJmNmbxViq27aOrAPWv2Y3xKMjGlGfwIWiYU9HhS-aKn9Jug24oxeISzxHA/s72-c/facebook-link-with-preview.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-8522741277553740146</id><published>2019-01-18T07:00:00.000+08:00</published><updated>2019-01-18T18:06:46.619+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Blogger"/><category scheme="http://www.blogger.com/atom/ns#" term="Twitter"/><title type='text'>Display Image in Twitter Card When Sharing Blogger Links</title><content type='html'>When you share a Blogger link on Twitter, it will appear as a simple link.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1XM5OFWN_RJO-kWNQdDAveZqas3jkAkhn3iBgoTA7fXTwLyLVXQLjPPcFECgKZeLIHXKLOvQkEFZe3ok7cQ2ICq5t16bvjckRHJU4lcd4hTpCpheDvgOpVOvVhtb56absJakLoQ/s1600/tweets-without-image-preview.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;202&quot; data-original-width=&quot;582&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1XM5OFWN_RJO-kWNQdDAveZqas3jkAkhn3iBgoTA7fXTwLyLVXQLjPPcFECgKZeLIHXKLOvQkEFZe3ok7cQ2ICq5t16bvjckRHJU4lcd4hTpCpheDvgOpVOvVhtb56absJakLoQ/s1600/tweets-without-image-preview.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Tweets with simple links&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;
No image previews, short description or anything at all. How boring.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I am sure you have seen tweets sharing content with websites that has a small image preview, article title and a short description. Wouldn&#39;t it be nice to have a preview when you share a link from your blog?&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhxBrvJkPG5DdTaAa161WCs-1N9ccTMyChON9mEBu3qTl0zGLYelNr3XEBLtVRpknrDHOqRrelyxmJEZIdmwZZg1UEUyI0jRKZubB4ttaQcSyx2PLRUBOJNS2SypCZhi2GNwt-JA/s1600/tweets-with-preview.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;506&quot; data-original-width=&quot;588&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhxBrvJkPG5DdTaAa161WCs-1N9ccTMyChON9mEBu3qTl0zGLYelNr3XEBLtVRpknrDHOqRrelyxmJEZIdmwZZg1UEUyI0jRKZubB4ttaQcSyx2PLRUBOJNS2SypCZhi2GNwt-JA/s1600/tweets-with-preview.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Links in Twitter now appear in card format, with image preview, title, description and web address&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Open Graph&lt;/h3&gt;The &lt;a href=&quot;http://ogp.me/&quot;&gt;Open Graph protocol&lt;/a&gt; is invented for precisely this reason. Instead of flat HTML pages with links to each other, the Open Graph is designed to turn the web pages into a rich object, and content can be connected in rich multimedia.&lt;br /&gt;
&lt;br /&gt;
Twitter has a &lt;a href=&quot;https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/markup&quot;&gt;well documented set of Twitter card tags&lt;/a&gt;. The information that you want to be displayed in your tweet are:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Your twitter username&lt;/li&gt;
&lt;li&gt;Your blog&#39;s domain&lt;/li&gt;
&lt;li&gt;Your blog post&#39;s URL&lt;/li&gt;
&lt;li&gt;Blog post title&lt;/li&gt;
&lt;li&gt;Blog post image&lt;/li&gt;
&lt;li&gt;Summary of your blog post&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;h3&gt;Blogger Template for Twitter Open Graph Sharing&lt;/h3&gt;&lt;div&gt;First, open up your Blogger settings and navigate to &lt;kbd&gt;Theme&lt;/kbd&gt; → &lt;kbd&gt;Edit HTML&lt;/kbd&gt; and scroll up to the beginning with the &lt;kbd&gt;html&lt;/kbd&gt; tag where the namespaces are defined. Add the Open Graph namespace at end of the HTML tag &lt;kbd&gt;xmlns:og=&#39;http://ogp.me/ns#&#39;&lt;/kbd&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
&amp;amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&amp;amp;gt;

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html b:render=&#39;false&#39; b:version=&#39;2&#39; class=&#39;v2&#39; expr:dir=&#39;data:blog.languageDirection&#39; xmlns=&#39;http://www.w3.org/1999/xhtml&#39; xmlns:b=&#39;http://www.google.com/2005/gml/b&#39; xmlns:data=&#39;http://www.google.com/2005/gml/data&#39; xmlns:expr=&#39;http://www.google.com/2005/gml/expr&#39; xmlns:og=&#39;http://ogp.me/ns#&#39;&amp;gt;


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Next, scroll down to just before the closing tag of &lt;kbd&gt;&amp;lt;/head&amp;gt;&lt;/kbd&gt; and add in these Twitter open graph tags&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
&amp;lt;!--START Twitter Card --&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;lt;meta content=&#39;summary&#39; name=&#39;twitter:card&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;lt;meta content=&#39;@hanxue&#39; name=&#39;twitter:site&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;lt;meta content=&#39;@hanxue&#39; name=&#39;twitter:creator&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;lt;meta expr:content=&#39;data:blog.homepageUrl&#39; name=&#39;twitter:domain&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;b:if cond=&#39;data:blog.pageType == &amp;amp;quot;item&amp;amp;quot;&#39;&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta expr:content=&#39;data:blog.canonicalUrl&#39; name=&#39;twitter:url&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta expr:content=&#39;data:blog.pageName&#39; name=&#39;twitter:title&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;b:else/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta expr:content=&#39;data:blog.homepageUrl&#39; name=&#39;twitter:url&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta expr:content=&#39;data:blog.pageTitle&#39; name=&#39;twitter:title&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/b:if&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;b:if cond=&#39;data:blog.postImageUrl&#39;&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta expr:content=&#39;data:blog.postImageUrl&#39; name=&#39;twitter:image&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;b:else/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta content=&#39;http://lh5.googleusercontent.com/-ArkTRuQev2U/AAAAAAAAAAI/AAAAAAAAGMk/Ml_6kHFDjDE/s512-c/photo.jpg&#39; name=&#39;twitter:image&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/b:if&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;b:if cond=&#39;data:blog.metaDescription&#39;&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;meta expr:content=&#39;data:blog.metaDescription&#39; name=&#39;twitter:description&#39;/&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/b:if&amp;gt;
&amp;nbsp; &amp;nbsp; &amp;lt;!--END Twitter Card --&amp;gt;
&amp;lt;/head&amp;gt;


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;The code above will associate all links from your blog share with your Twitter username. The code also check if the link is a blog article. If it is, the complete article link is shown on Twitter, together with the article&#39;s title. Otherwise if you are simply sharing your blog&#39;s address, it will show your blog&#39;s home address and title.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Likewise, your Twitter Card will only a preview of the first image on your article. If there are no image found, for example if you are sharing your blog&#39;s home page or tags or categories, then it will use the blog profile image that you specify.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;And finally if you are sharing your blog&#39;s home page or categories, Twitter will display your blog&#39;s description. Otherwise, it will get the description from the article content directly.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Copy and paste the code from above, and remember to change these 3 values&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;kbd&gt;twitter:site&lt;/kbd&gt; - Your twitter account. Mine is &lt;a href=&quot;https://twitter.com/hanxue&quot;&gt;@hanxue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;twitter:creator&lt;/kbd&gt; - Your twitter account. Mine is&amp;nbsp;&lt;a href=&quot;https://twitter.com/hanxue&quot;&gt;@hanxue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;kbd&gt;twitter:image&lt;/kbd&gt; - The profile image of your blog&lt;/li&gt;
&lt;/ul&gt;If you don&#39;t change the 3 values, especially &lt;kbd&gt;twitter:image&lt;/kbd&gt;, the Twitter link to your blog will end up like this&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghhQRDprjoa29EGoUtHTcqy85X4NjlgtklkYD8XAJjdbWB46hrHmo7KckBqzI5Wb857Lp2xEQKG-Vvo0AqOfWkTcBnW4WkBJWfwFcvFsY1Yn5_Gsq-EHKtx4xeTodfhle1HlzcNA/s1600/hanxue-twitter-blog.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;252&quot; data-original-width=&quot;541&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghhQRDprjoa29EGoUtHTcqy85X4NjlgtklkYD8XAJjdbWB46hrHmo7KckBqzI5Wb857Lp2xEQKG-Vvo0AqOfWkTcBnW4WkBJWfwFcvFsY1Yn5_Gsq-EHKtx4xeTodfhle1HlzcNA/s1600/hanxue-twitter-blog.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Hanxue&#39;s blog, shared on Twitter&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Validating Twitter Cards&lt;/h3&gt;&lt;div&gt;Before you start sharing, you can validate the links to your blog posts at&amp;nbsp;&lt;a href=&quot;https://cards-dev.twitter.com/validator&quot;&gt;https://cards-dev.twitter.com/validator&lt;/a&gt;&amp;nbsp;For example, this is what I see&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPe44_ov5LxVo9N2kXJ0zKLn2ve7l_iuaZgoQw8h360jH26IufHGXAQvUri9HrqDUHkWWN5lU52VkU8ijZY84MyM1jS4lbUlyq78wA2jP-MslCFUq7cHX5b8gDuUorKIj3QpdYiA/s1600/twitter-card-validator.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;568&quot; data-original-width=&quot;1011&quot; height=&quot;358&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPe44_ov5LxVo9N2kXJ0zKLn2ve7l_iuaZgoQw8h360jH26IufHGXAQvUri9HrqDUHkWWN5lU52VkU8ijZY84MyM1jS4lbUlyq78wA2jP-MslCFUq7cHX5b8gDuUorKIj3QpdYiA/s640/twitter-card-validator.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Twitter Card Validator in action&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/8522741277553740146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/8522741277553740146' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/8522741277553740146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/8522741277553740146'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/display-image-in-twitter-card-when-sharing-blogger-links.html' title='Display Image in Twitter Card When Sharing Blogger Links'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1XM5OFWN_RJO-kWNQdDAveZqas3jkAkhn3iBgoTA7fXTwLyLVXQLjPPcFECgKZeLIHXKLOvQkEFZe3ok7cQ2ICq5t16bvjckRHJU4lcd4hTpCpheDvgOpVOvVhtb56absJakLoQ/s72-c/tweets-without-image-preview.png" height="72" width="72"/><thr:total>6</thr:total><georss:featurename>Klang, Selangor, Malaysia</georss:featurename><georss:point>3.044917 101.44556209999996</georss:point><georss:box>2.791217 101.12283859999997 3.2986169999999997 101.76828559999996</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-4180929467426597932</id><published>2019-01-17T06:30:00.000+08:00</published><updated>2019-01-18T18:26:39.200+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bash"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Shell"/><title type='text'>Bash: Show execution time for each command in the shell</title><content type='html'>We can measure the execution time of a command with &lt;kbd&gt;time&lt;/kbd&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ time yarn audit
yarn audit v1.12.3
--- output truncated ---
6 vulnerabilities found - Packages audited: 34977
Severity: 1 Low | 4 High | 1 Critical
✨&amp;nbsp; Done in 6.58s.

real&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;0m7.083s
user&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;0m2.149s
sys&lt;span style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;0m0.199s



&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
But having to pre-pend &lt;kbd&gt;time&lt;/kbd&gt; with each command is a pain. Wouldn&#39;t it be nice to have the bash prompt display the time taken for the last command?&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
[last: 6s]&amp;nbsp;$ yarn audit


&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;Elapsed Time for Last Command&lt;/h3&gt;We cannot use the &lt;kbd&gt;time&lt;/kbd&gt; command to set the shell prompt. Fortunately bash has a special &lt;kbd&gt;SECONDS&lt;/kbd&gt; &lt;a href=&quot;https://www.tldp.org/LDP/abs/html/internalvariables.html&quot;&gt;internal variable that tracks the number of seconds the script has been running.&lt;/a&gt;&amp;nbsp;There is also &lt;kbd&gt;PROMPT_COMMAND&lt;/kbd&gt;, a variable that holds the command to be executed just before the prompt is displayed. Finally, we can start the timer by using the &lt;kbd&gt;DEBUG&lt;/kbd&gt; &lt;a href=&quot;https://www.tldp.org/LDP/abs/html/debugging.html#TRAPREF1&quot;&gt;trap&lt;/a&gt;, then stop the timer just before the shell prompt is shown.&lt;br /&gt;
&lt;br /&gt;
Putting it all together:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
function timer_start {
&amp;nbsp; timer=${timer:-$SECONDS}
}

function timer_stop {
&amp;nbsp; timer_show=$(($SECONDS - $timer))
&amp;nbsp; unset timer
}

trap &#39;timer_start&#39; DEBUG
PROMPT_COMMAND=timer_stop

PS1=&#39;[last: ${timer_show}s][\W]$ &#39;



&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Colored Bash Prompt&lt;/h3&gt;Having a shell prompt in white is boring. Why not colorize the output? Use &lt;a href=&quot;http://ezprompt.net/&quot;&gt;this website to help you to generate the shell prompt syntax&lt;/a&gt;. I have added different colors for the time and the current working directory with this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
PS1=&#39;[\[\033[36m\]last:\[\033[m\] \[\033[32m\]${timer_show}s\[\033[m\]] \[\033[33;1m\]\W\[\033[m\]\$ &#39;



&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;This is how it looks like&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh35Y4Zg51j_09L-xVeDsWA6ObVtlVHm0j1fBBocTiGMTDaFXt-kJuFOLEnf9eu5cA1_2HlC4fJI6zJJ4QyqyB7oZJsXCCEBCq1t7NzALh7sV9JKi_jtoOaOOMcPlroSvUZ_Qvn_A/s1600/shell_prompt_with_time.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;390&quot; data-original-width=&quot;570&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh35Y4Zg51j_09L-xVeDsWA6ObVtlVHm0j1fBBocTiGMTDaFXt-kJuFOLEnf9eu5cA1_2HlC4fJI6zJJ4QyqyB7oZJsXCCEBCq1t7NzALh7sV9JKi_jtoOaOOMcPlroSvUZ_Qvn_A/s1600/shell_prompt_with_time.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div&gt;Note that the elapsed time include the idle time from the previously completed command.&amp;nbsp;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/4180929467426597932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/4180929467426597932' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/4180929467426597932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/4180929467426597932'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/bash-show-execution-time-for-each-command-in-the-shell.html' title='Bash: Show execution time for each command in the shell'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh35Y4Zg51j_09L-xVeDsWA6ObVtlVHm0j1fBBocTiGMTDaFXt-kJuFOLEnf9eu5cA1_2HlC4fJI6zJJ4QyqyB7oZJsXCCEBCq1t7NzALh7sV9JKi_jtoOaOOMcPlroSvUZ_Qvn_A/s72-c/shell_prompt_with_time.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-5998971403607267228</id><published>2019-01-16T23:30:00.000+08:00</published><updated>2019-01-18T18:29:29.897+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="vscode"/><title type='text'>How to tidy up code using Visual Studio Code</title><content type='html'>Have you come across jumbled up code that you wish you can format? This article will show you how to format code using Visual Studio Code. &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode&quot;&gt;Install the Prettier vscode&amp;nbsp; extension&lt;/a&gt;&amp;nbsp; and reload Visual Studio Code. You will now see a &lt;b&gt;Format Document&lt;/b&gt;&amp;nbsp;command.&lt;br /&gt;
&lt;br /&gt;
&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpexXZm6DDB0jdbGfBztlkdtBDtStZ3DuJWALmbiSIytn_BrUIeRZbvDT3munfqpkD2cc57Z1GkweI76XF2F0La8bYS4yX1V32R6jOzi_Eu0jLvPhYbICI0nDw5yMhRJRjrIPE-A/s1600/vscode-format-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;125&quot; data-original-width=&quot;795&quot; height=&quot;100&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpexXZm6DDB0jdbGfBztlkdtBDtStZ3DuJWALmbiSIytn_BrUIeRZbvDT3munfqpkD2cc57Z1GkweI76XF2F0La8bYS4yX1V32R6jOzi_Eu0jLvPhYbICI0nDw5yMhRJRjrIPE-A/s640/vscode-format-2.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Visual Studio Code Format Document command&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;The keyboard shortcuts are:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Windows &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Alt&lt;/kbd&gt; + &lt;kbd&gt;F&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;Mac &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Option&lt;/kbd&gt; + &lt;kbd&gt;F&lt;/kbd&gt;&lt;/li&gt;
&lt;li&gt;Linux &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;F&lt;/kbd&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Beautify Javascript Code&lt;/h3&gt;&lt;div&gt;Modern published Javascript code is uglified to reduce the file size and increase performance. Take for example this snippet from a Chrome extension&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class=&quot;prettyprint lang-js&quot;&gt;&lt;code&gt;
var h=function(a,b){function c(){}c.prototype=b.prototype;a.f=b.prototype;a.prototype=new c;a.e=function(a,c,g){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Running the &lt;b&gt;Format Document&lt;/b&gt;&amp;nbsp;command will result in&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-js&quot;&gt;&lt;code&gt;
var h = function(a, b) {
&amp;nbsp; function c() {}
&amp;nbsp; c.prototype = b.prototype
&amp;nbsp; a.f = b.prototype
&amp;nbsp; a.prototype = new c()
&amp;nbsp; a.e = function(a, c, g) {
&amp;nbsp; &amp;nbsp; return b.prototype[c].apply(a, Array.prototype.slice.call(arguments, 2))
&amp;nbsp; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;h3&gt;Formatting XML Code&lt;/h3&gt;&lt;div&gt;The second example I have here is a Blogger Dynamic View Template which contains a very long line.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVu3v6H3TLlO76vpbB1eRisqsl1UbGRhqB8XxSYylVSDMXOGhOZD089K5k5VJGJgfnpcArUhXVuCif2sxri7hN4anB2DBoggQR24tEZkhISEM77t-O-zt6z99L2vqjk9ecdEslig/s1600/tidy-code-1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;353&quot; data-original-width=&quot;813&quot; height=&quot;276&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVu3v6H3TLlO76vpbB1eRisqsl1UbGRhqB8XxSYylVSDMXOGhOZD089K5k5VJGJgfnpcArUhXVuCif2sxri7hN4anB2DBoggQR24tEZkhISEM77t-O-zt6z99L2vqjk9ecdEslig/s640/tidy-code-1.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Jumbled up code from Blogger template&lt;br /&gt;
&lt;br /&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;Cannot make out head or tail of the code? Open up a new tab in Visual Studio Code, and paste the line. Then run &lt;b&gt;Format Document&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIFuqQpAlWosiiHgsv2DgmTjZlLwAYgGOkeQGBrOQvYnM4X4eQ0WktSisag28iZMow_upUuKwyUjOHyz1s1VXcv2VZNIIKrbqs-bW5k4UKxEwBDrew43JvpL_ZhsMdqdNAuD1NXw/s1600/tidy-code-3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;72&quot; data-original-width=&quot;453&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIFuqQpAlWosiiHgsv2DgmTjZlLwAYgGOkeQGBrOQvYnM4X4eQ0WktSisag28iZMow_upUuKwyUjOHyz1s1VXcv2VZNIIKrbqs-bW5k4UKxEwBDrew43JvpL_ZhsMdqdNAuD1NXw/s1600/tidy-code-3.png&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;No document formatter for plaintext file&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;Oops, Visual Studio Code is complaining that there is no document formatter installed. Our code snippet is loaded on an unsaved buffer, and is detected as &lt;kbd&gt;plain text&lt;/kbd&gt; by default. Simply change the type to &lt;kbd&gt;HTML&lt;/kbd&gt; and run &lt;kbd&gt;Format Document&lt;/kbd&gt; again. The result should be similar to this&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre class=&quot;prettyprint lang-html&quot;&gt;&lt;code&gt;
&amp;lt;b:if cond=&quot;data:top.showEmailButton&quot;
  &amp;gt;&amp;lt;a
    class=&quot;goog-inline-block share-button sb-email&quot;
    expr:href=&quot;data:post.sharePostUrl + &amp;quot;&amp;amp;target=email&amp;quot;&quot;
    expr:title=&quot;data:top.emailThisMsg&quot;
    target=&quot;_blank&quot;
    &amp;gt;&amp;lt;span class=&quot;share-button-link-text&quot;
      &amp;gt;&amp;lt;data:top.emailThisMsg /&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/b:if
&amp;gt;&amp;lt;b:if cond=&quot;data:top.showBlogThisButton&quot;
  &amp;gt;&amp;lt;a
    class=&quot;goog-inline-block share-button sb-blog&quot;
    expr:href=&quot;data:post.sharePostUrl + &amp;quot;&amp;amp;target=blog&amp;quot;&quot;
    expr:onclick=&quot;&amp;quot;window.open(this.href, \&amp;quot;_blank\&amp;quot;, \&amp;quot;height=270,width=475\&amp;quot;); return false;&amp;quot;&quot;
    expr:title=&quot;data:top.blogThisMsg&quot;
    target=&quot;_blank&quot;
    &amp;gt;&amp;lt;span class=&quot;share-button-link-text&quot;
      &amp;gt;&amp;lt;data:top.blogThisMsg /&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/b:if
&amp;gt;


&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Prettier supports a few popular programming languages out of the box. You will need to install other language extensions in order for Prettier to work. A useful workaround is to save a copy of your source code, say &lt;b&gt;Main.groovy&lt;/b&gt;&amp;nbsp;to &lt;b&gt;Main.js&lt;/b&gt;. You can now apply the &lt;b&gt;Format Document&lt;/b&gt;&amp;nbsp;command.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;table align=&quot;center&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; class=&quot;tr-caption-container&quot; style=&quot;margin-left: auto; margin-right: auto; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheda9vCjvgAjGH18d6EEBQ7GeJu2mzLHoTMTn2Airp6k2lT4hi9fDZI19GbSeBHppUugmq0-o1joigyI4BFw8a0ldTdj6viBVNCJbaYtqfqfSMLpYSKuIzzLn7aZg0UUKafrElaA/s1600/visual-studio_code-logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: auto; margin-right: auto;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;240&quot; data-original-width=&quot;480&quot; height=&quot;160&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheda9vCjvgAjGH18d6EEBQ7GeJu2mzLHoTMTn2Airp6k2lT4hi9fDZI19GbSeBHppUugmq0-o1joigyI4BFw8a0ldTdj6viBVNCJbaYtqfqfSMLpYSKuIzzLn7aZg0UUKafrElaA/s320/visual-studio_code-logo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;tr-caption&quot; style=&quot;text-align: center;&quot;&gt;Visual Studio Code logo&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/5998971403607267228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/5998971403607267228' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/5998971403607267228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/5998971403607267228'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/how-to-format-code-using-visual-studio-code.html' title='How to tidy up code using Visual Studio Code'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpexXZm6DDB0jdbGfBztlkdtBDtStZ3DuJWALmbiSIytn_BrUIeRZbvDT3munfqpkD2cc57Z1GkweI76XF2F0La8bYS4yX1V32R6jOzi_Eu0jLvPhYbICI0nDw5yMhRJRjrIPE-A/s72-c/vscode-format-2.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-8194055940518518629</id><published>2019-01-16T07:00:00.000+08:00</published><updated>2019-01-16T18:40:15.544+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="node"/><category scheme="http://www.blogger.com/atom/ns#" term="windows"/><category scheme="http://www.blogger.com/atom/ns#" term="yarn"/><title type='text'>How to speed up building of npm packages on Windows</title><content type='html'>Building node.js projects on Windows can be significantly slower than on Linux or macOS. Assuming that you have a fast SSD and plenty of RAM, building a large node.js project is often slowed by Antivirus.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/yarnpkg/yarn/issues/990#issuecomment-278516972&quot;&gt;Testing by keawade&lt;/a&gt; shows that Yarn build time is 54% slower when Windows Defender is enabled, and disk indexing for the project directory is enabled.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1B2YA7lZ2AxefNsV2AP0F9lKVia1gEgRbcP5A3mshapH4Et_lDTtGcI9wlkCIXtnp71U1EoFeN-F1tbM-7vYfxY3_u0bgzX-TdZem3w-18a1LQ8Aff1yopy5JgPB4N8t8hqyw1w/s1600/yarn_build_time.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;393&quot; data-original-width=&quot;675&quot; height=&quot;372&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1B2YA7lZ2AxefNsV2AP0F9lKVia1gEgRbcP5A3mshapH4Et_lDTtGcI9wlkCIXtnp71U1EoFeN-F1tbM-7vYfxY3_u0bgzX-TdZem3w-18a1LQ8Aff1yopy5JgPB4N8t8hqyw1w/s640/yarn_build_time.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;a href=&quot;https://github.com/yarnpkg/yarn/issues/990#issuecomment-290651417&quot;&gt;A separate test by vbfox&lt;/a&gt; shows that with similar hardware on Windows and Antivirus disabled, the performance is comparable to macOS.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiGKTiXi51JNndVQxMTXG_4f9i2s2f37oDddI5sv2_4PwyRzGHvR3p_DI-9F9saJbdFrAN5QNVwxfDnyR1QrUkF7ktPivlz8y3Zz2R1ac30LuWy8ttcmRMLMd09YNAACstxfDU7w/s1600/yarn_benchmark.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;388&quot; data-original-width=&quot;691&quot; height=&quot;359&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiGKTiXi51JNndVQxMTXG_4f9i2s2f37oDddI5sv2_4PwyRzGHvR3p_DI-9F9saJbdFrAN5QNVwxfDnyR1QrUkF7ktPivlz8y3Zz2R1ac30LuWy8ttcmRMLMd09YNAACstxfDU7w/s640/yarn_benchmark.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
The test shows that simply copying the &lt;kbd&gt;node_modules&lt;/kbd&gt; folder can be much faster when the folders are excluded by the antivirus software.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Exclude Indexing for node_modules&lt;/h3&gt;Since there is no use for the content of &quot;node_modules&quot; to appear in Windows search results, exclude the &quot;node_modules&quot; folder. I exclude the folder containing all my projects. My editor (Visual Studio Code) already has excellent search functionality. On the command line, I &lt;a href=&quot;https://github.com/monochromegane/the_platinum_searcher&quot;&gt;use the platinum searcher&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH94xDVSVqoOaX4nutUxRRuXn3TaWuDukLn5OSh9P9uPEZBCgnASeRc7Jfu1nAxcvaPPUYfnVHLdaH3yS5Ngr5h4fUXrm_1qH8Vfl0T0eLO5opwGsCQGdN62DD2bJ2z3SZlJOXTg/s1600/windows_10_index.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;577&quot; data-original-width=&quot;402&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH94xDVSVqoOaX4nutUxRRuXn3TaWuDukLn5OSh9P9uPEZBCgnASeRc7Jfu1nAxcvaPPUYfnVHLdaH3yS5Ngr5h4fUXrm_1qH8Vfl0T0eLO5opwGsCQGdN62DD2bJ2z3SZlJOXTg/s1600/windows_10_index.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/windows/desktop/bb266513%28v=vs.85%29.aspx&quot;&gt;If you are feeling adventurous&lt;/a&gt;, you can edit the registry key &lt;kbd&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Search\CrawlScopeManager\Windows\SystemIndex\&lt;/kbd&gt; to exclude by Wildcard&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;For those interested, you can modify these defaults and add your own by turning off the search service, modifying the registry and restarting the service. The applicable keys are located here:&lt;br /&gt;
&lt;br /&gt;
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Search\CrawlScopeManager\Windows\SystemIndex\&lt;br /&gt;
&lt;br /&gt;
Any overrides you specify show up in the WorkingSetRules key. This supports wildcards so you can exclude, say, node_modules, .git .svn, etc. from search indexing. tswaters 8/1/2015&lt;/blockquote&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Exclude Indexing for Yarn Cache&lt;/h3&gt;Likewise, exclude the &lt;kbd&gt;%LocalAppData%\Yarn&lt;/kbd&gt; folder from Windows Indexing. This folder is updated every time you run an &lt;kbd&gt;add&lt;/kbd&gt;, &lt;kbd&gt;update&lt;/kbd&gt; or &lt;kbd&gt;install&lt;/kbd&gt; command in Yarn.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Antivirus Whitelist&lt;/h3&gt;You should also whitelist your project folder (or at least the node_modules folder) and the Yarn Cache in your antivirus application. &lt;a href=&quot;https://support.microsoft.com/en-us/help/4028485/windows-10-add-an-exclusion-to-windows-security&quot;&gt;Instructions to whitelist in Windows Security&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq3zLNvUVG_IAGymr-CVo6XpYOmQWucqo_kGsa1zFQbHr0H9UVkuVQKLAnROuj-Qpr2vLp1ZeiTGUnBj9rn-NrftkSoWMWFRdqcG6vy-I3KJD9vT9zPUPDJASxUJWH9RzRF6rsfg/s1600/windows_defender_add_exclusion.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;317&quot; data-original-width=&quot;558&quot; height=&quot;363&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhq3zLNvUVG_IAGymr-CVo6XpYOmQWucqo_kGsa1zFQbHr0H9UVkuVQKLAnROuj-Qpr2vLp1ZeiTGUnBj9rn-NrftkSoWMWFRdqcG6vy-I3KJD9vT9zPUPDJASxUJWH9RzRF6rsfg/s640/windows_defender_add_exclusion.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Also exclude the &lt;kbd&gt;node.exe&lt;/kbd&gt; process from antivirus scanning - this is the process that has very high I/O.&lt;br /&gt;
&lt;br /&gt;
In terms of application choices, certain corporate antivirus products can cause an order of a magnitude slowdown. Yarn is also easily 5x faster than npm on average.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;Summary&lt;/h3&gt;Here are the steps you can take on Windows to increase node.js performance&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Use &lt;b&gt;yarn&lt;/b&gt; instead of &lt;b&gt;npm&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Have adequate hardware - SSD and sufficient RAM&lt;/li&gt;
&lt;li&gt;Whitelist node.exe, node_modules or the project folder and Yarn / NPM cache in your antivirus application&lt;/li&gt;
&lt;li&gt;Exclude indexing of your project folder and the Yarn / NPM cache&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/8194055940518518629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/8194055940518518629' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/8194055940518518629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/8194055940518518629'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/how-to-speed-up-building-of-npm-packages-on-windows-yarn-npm.html' title='How to speed up building of npm packages on Windows'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1B2YA7lZ2AxefNsV2AP0F9lKVia1gEgRbcP5A3mshapH4Et_lDTtGcI9wlkCIXtnp71U1EoFeN-F1tbM-7vYfxY3_u0bgzX-TdZem3w-18a1LQ8Aff1yopy5JgPB4N8t8hqyw1w/s72-c/yarn_build_time.png" height="72" width="72"/><thr:total>1</thr:total><georss:featurename>Klang, Selangor, Malaysia</georss:featurename><georss:point>3.044917 101.44556209999996</georss:point><georss:box>2.791217 101.12283859999997 3.2986169999999997 101.76828559999996</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-5116696153541612823</id><published>2019-01-15T13:04:00.000+08:00</published><updated>2019-01-15T13:04:07.864+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><title type='text'>Linux: Move swap to RAM</title><content type='html'>Linux will use swap memory if a swap partition is available. But swapping memory into RAM is much slower than simply using physical RAM. What if your machine has plenty of physical RAM and you want Linux to avoid using swap?&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://help.ubuntu.com/community/SwapFaq#Empty_Swap&quot;&gt;This script will check&lt;/a&gt; if the amount of free RAM is more than the swap memory that is being used. If there is sufficient free RAM, then swap memory will be turned off, flushing all swapped memory into RAM. Finally, swap memory is turned on again in case it is needed.&lt;br /&gt;
&lt;br /&gt;
Create a file called&amp;nbsp;&lt;kbd&gt;/usr/local/sbin/swap2ram.sh&lt;/kbd&gt; with the following content&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
#!/bin/sh

mem=$(LC_ALL=C free&amp;nbsp; | awk &#39;/Mem:/ {print $4}&#39;)
swap=$(LC_ALL=C free | awk &#39;/Swap:/ {print $3}&#39;)

if [ $mem -lt $swap ]; then
&amp;nbsp; &amp;nbsp; echo &quot;ERROR: not enough RAM to write swap back, nothing done&quot; &amp;gt;&amp;amp;2
&amp;nbsp; &amp;nbsp; exit 1
fi

swapoff -a &amp;amp;&amp;amp;
swapon -a


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Add executable permission to the script&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
chmod +x /usr/local/sbin/swap2ram.sh


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
And finally add this script into &lt;b&gt;root&lt;/b&gt;&#39;s cronjob&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo crontab -e


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;a href=&quot;https://crontab.guru/#3_*_*_*_*&quot;&gt;Set it to run every hour on the 3rd minute&lt;/a&gt;. This is the crontab entry&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
3 * * * * /usr/local/sbin/swap2ram.sh

&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM9u6gUY-SLfAIEUnZ1N3Gu5lBnJX2vzegD-BSw-4c4sdm8CN_NqaOjRX1yoPnaTCclTUXDIOgLoTniJsdFqyW3sNY4A41jyTpilr_l4UWKvG1OYdFkKQc-EKt0FwZY03iOCxjBg/s1600/debian-logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;232&quot; data-original-width=&quot;480&quot; height=&quot;154&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM9u6gUY-SLfAIEUnZ1N3Gu5lBnJX2vzegD-BSw-4c4sdm8CN_NqaOjRX1yoPnaTCclTUXDIOgLoTniJsdFqyW3sNY4A41jyTpilr_l4UWKvG1OYdFkKQc-EKt0FwZY03iOCxjBg/s320/debian-logo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/5116696153541612823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/5116696153541612823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/5116696153541612823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/5116696153541612823'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/linux-move-swap-memory-to-ram-physical-memory-crontab.html' title='Linux: Move swap to RAM'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM9u6gUY-SLfAIEUnZ1N3Gu5lBnJX2vzegD-BSw-4c4sdm8CN_NqaOjRX1yoPnaTCclTUXDIOgLoTniJsdFqyW3sNY4A41jyTpilr_l4UWKvG1OYdFkKQc-EKt0FwZY03iOCxjBg/s72-c/debian-logo.png" height="72" width="72"/><thr:total>0</thr:total><georss:featurename>Klang, Selangor, Malaysia</georss:featurename><georss:point>3.044917 101.44556209999996</georss:point><georss:box>2.791217 101.12283859999997 3.2986169999999997 101.76828559999996</georss:box></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-582288870802634548</id><published>2019-01-13T16:49:00.000+08:00</published><updated>2019-01-13T16:50:52.087+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="yarn"/><title type='text'>Configuring yarn cache</title><content type='html'>yarn, similar to npm, utilizes a cache. When you run &lt;kbd&gt;yarn add package&lt;/kbd&gt; or &lt;kbd&gt;yarn install&lt;/kbd&gt;, yarn does not simply fetch the package and save it directly into your project&#39;s &quot;node_modules/package&quot;. It will at least have to fetch the compressed tarball, verify the integrity of the package and then unpack it.&lt;br /&gt;
&lt;br /&gt;
The yarn cache avoids repeatedly downloaded the same package.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Cache Directory&lt;/h3&gt;
You can find out the cache location with the command&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ yarn cache dir
/Users/hanxue/Library/Caches/Yarn/v4


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
Temporary Cache&lt;/h3&gt;
If you do not want to keep the cached packages, you can temporarily set a different cache location with the &lt;kbd&gt;--cache-folder&lt;/kbd&gt; flag&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ yarn install --prod --cache-folder /tmp/ycache; rm -Rf /tmp/ycache


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
Docker and Temporary Yarn Cache&lt;/h3&gt;
When creating a Docker image, you almost certainly do not want the files in the yarn cache to be saved. The contents of &lt;kbd&gt;node_modules/&lt;/kbd&gt; are sufficient for your application to work.&lt;br /&gt;
&lt;br /&gt;
One workaround is to change the Yarn Cache to use Docker&#39;s &lt;kbd&gt;shm&lt;/kbd&gt; temporary file system, with this command in your &lt;kbd&gt;Dockerfile&lt;/kbd&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
RUN YARN_CACHE_FOLDER=/dev/shm/yarn_cache yarn --production


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The default &lt;kbd&gt;shm&lt;/kbd&gt; filesystem is only 64MB, and you may need to increase it to an appropriate size, for example&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ docker build -t my-image --shm-size 512M .


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
Clearing the Yarn Cache&lt;/h3&gt;
You can remove the contents of the yarn cache with&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ yarn cache clean


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Alternatively, if you just wish to remove a single package from the cache, you can specify the package name&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
$ yarn cache clean lodash


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h3&gt;
Search for Package in the Cache&lt;/h3&gt;
You can search for packages in the yarn cache&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
yarn cache list --pattern gulp
yarn cache list --pattern &quot;gulp|grunt&quot;
yarn cache list --pattern &quot;gulp-(match|newer)&quot;


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Leaving out &lt;kbd&gt;--pattern&lt;/kbd&gt; will simply list the complete content of your yarn cache&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
yarn cache list


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h2&gt;
Difference with NPM Cache&lt;/h2&gt;
One major difference that you may need to be aware, npm uses the &lt;kbd&gt;cache&lt;/kbd&gt; key to set the cache folder, while yarn uses &lt;kbd&gt;cache-folder&lt;/kbd&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
yarn config set cache-folder /mnt/vol2/yarn-cache


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
You can run just about any yarn &lt;kbd&gt;command&lt;/kbd&gt; while specifying the alternative cache location&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
yarn add package --cache-folder /mnt/vol2/yarn-cache


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
For more information, &lt;a href=&quot;https://yarnpkg.com/en/docs/cli/cache&quot;&gt;refer to the Yarn cache command documentation&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
Cannot Set Cache Outside of Application Directory&lt;/h2&gt;
If you cannot write to any other directory such as &lt;kbd&gt;/tmp&lt;/kbd&gt; or &lt;kbd&gt;/dev/shm&lt;/kbd&gt;, you can trick yarn to use your current directory by setting the &lt;kbd&gt;HOME&lt;/kbd&gt; environment variable&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
HOME=$(pwd) yarn install


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h2&gt;
Disabling the Cache&lt;/h2&gt;
Currently there is no way to avoid the use of the yarn cache. There is a proposal to add this option, &lt;a href=&quot;https://github.com/yarnpkg/rfcs/pull/53&quot;&gt;so please vote to show your support&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Git Branch Dependency Does Not Update&lt;/h3&gt;
If you run&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
yarn add org/package#branch_name


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
and &lt;kbd&gt;branch_name&lt;/kbd&gt; is updated, yarn will simply use the cached content instead of fetching the new commits.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;
Use Git Commit&lt;/h4&gt;
Instead of using the branch name, use the commit id instead&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
yarn add org/package#3ea9fe7984b9005f3cc62b14ee4018013ae0db0f


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h4&gt;
Use Tarball&lt;/h4&gt;
If you are adding from Github, you can also specify the tarball URL&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
yarn add package https://github.com/org/package/tarball/3ea9fe7984b9005f3cc62b14ee4018013ae0db0f/package.tar.gz


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;h2&gt;
Concurrently Updating The Yarn Cache&lt;/h2&gt;
If there are multiple instances of yarn running on the same machine as the same user, for example a CI tool such as Jenkins running yarn, you might run into errors such as&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
23:33:24 +0000 verbose 1.293 Error: https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz: ENOENT: no such file or directory, chmod &#39;/var/lib/jenkins/.cache/yarn/v1/npm-file-type-3.9.0-257a078384d1db8087bc449d107d52a52672b9e9/package.json&#39;
23:33:24 +0000 error An unexpected error occurred: &quot;https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz: ENOENT: no such file or directory, chmod &#39;/var/lib/jenkins/.cache/yarn/v1/npm-file-type-3.9.0-257a078384d1db8087bc449d107d52a52672b9e9/package.json&#39;&quot;


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
The solution is to use the&amp;nbsp; &lt;kbd&gt;--mutex&lt;/kbd&gt; flag. Either one of the commands below will work&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
yarn command --mutex file
yarn command --mutex file:/tmp/.yarn-mutex
yarn command --mutex network
yarn command --mutex network:30330



&lt;/code&gt;&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWA8krC8KqL6S07ZWoRCpL80JH0ESdN6DMAi7Cor5D6JCjLW23Uj2jJ0JJ3iaR8axeCkiXPdehbG7Guaz3eR8iOXD2laZ-MlWsvMGuMet0GP0NY_XDQ4l_uSpmt6c0zUEfo1gchA/s1600/yarn_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;838&quot; data-original-width=&quot;1600&quot; height=&quot;167&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWA8krC8KqL6S07ZWoRCpL80JH0ESdN6DMAi7Cor5D6JCjLW23Uj2jJ0JJ3iaR8axeCkiXPdehbG7Guaz3eR8iOXD2laZ-MlWsvMGuMet0GP0NY_XDQ4l_uSpmt6c0zUEfo1gchA/s320/yarn_logo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/582288870802634548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/582288870802634548' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/582288870802634548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/582288870802634548'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/configuring-yarn-cache.html' title='Configuring yarn cache'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWA8krC8KqL6S07ZWoRCpL80JH0ESdN6DMAi7Cor5D6JCjLW23Uj2jJ0JJ3iaR8axeCkiXPdehbG7Guaz3eR8iOXD2laZ-MlWsvMGuMet0GP0NY_XDQ4l_uSpmt6c0zUEfo1gchA/s72-c/yarn_logo.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7389078.post-2528491712509705043</id><published>2019-01-11T20:37:00.001+08:00</published><updated>2019-01-11T20:37:26.347+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="troubleshooting"/><title type='text'>Debian: no network connection even after restarting network manager</title><content type='html'>My colleague had an issue with a Debian machine that fails to connect to the Internet even though the Network Manager is restarted. This machine has a script that detects network connection, and if the connection is down. When the connection is down, the Network Manager service is restarted. Presumably the command is&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo /etc/init.d/network-manager restart


&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;
Restart the Network Stack&lt;/h3&gt;
Note that &lt;kbd&gt;network-manager&lt;/kbd&gt; is a client GUI service and restarting it should also restarting the network stack. But really what we want is to restart the network stack directly&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo /etc/init.d/networking restart


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Using &lt;kbd&gt;systemd&lt;/kbd&gt;, run&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo systemctl restart networking


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
You can restart the network stack directly without using the System V init or SystemD systems&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo ifdown --exclude=lo -a &amp;amp;&amp;amp; sudo ifup --exclude=lo -a


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Flush DNS Cache&lt;/h3&gt;
Although the problem was eventually solved with a reboot, the actual cause was not known. When we restart the networking service, we tend to think everything that is related to network connectivity is restarted, including the DNS cache. From my experience providing support for large Linux environments, a common problem with networking is corrupted or outdated DNS cache.&lt;br /&gt;
&lt;br /&gt;
We often face this issue on our laptop when there is internet connectivity, but some websites do not work on the web browser. Pinging the IP address works, but &lt;kbd&gt;nslookup&lt;/kbd&gt; or &lt;kbd&gt;dig&lt;/kbd&gt; fails. Simply restarting the networking services will not solve the problem.&lt;br /&gt;
&lt;br /&gt;
On a newer Debian machine or Ubuntu 17.04 and above, you can flush the DNS cache with the command&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo systemd-resolve --flush-caches


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
On other versions of Debian and Ubuntu, &lt;kbd&gt;dnsmasq&lt;/kbd&gt; is used for DNS caching. You can restart it with&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo /etc/init.d/dnsmasq restart


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
or&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo kill -HUP $(pgrep dnsmasq)


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
For Ubuntu&amp;nbsp;11.10 and older Debian machines, DNS records are not cached. Chances are, the system administrator might have installed a DNS caching service such as &lt;kbd&gt;nscd&lt;/kbd&gt;. Restart nscd with&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo /etc/init.d/nscd reload


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
On a side note, nscd is known to be buggy. I used experience a lot of OpenLDAP failures that is traced back to nscd. Use &lt;a href=&quot;https://packages.debian.org/search?keywords=pdnsd&quot;&gt;another DNS caching service such as pdnsd instead&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Another popular DNS caching server is BIND&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint lang-sh&quot;&gt;&lt;code&gt;
sudo /etc/init.d/named restart


&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
There could be other DNS servers or caching services that is running. Check &lt;kbd&gt;/etc/resolv.conf&lt;/kbd&gt; or &lt;a href=&quot;https://wiki.debian.org/NetworkConfiguration#DNS_configuration_for_NetworkManager&quot;&gt;your Network Manager settings to see if any DNS service is used&lt;/a&gt;, and restart them appropriately.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsKUm5STou9Pqkw2Av_v17D5f7ez2dFmoptuM2NTX1vuGJRP3A1Se5PLuQMCZV8nfG73evQJJ_EUdO9IIlhVuUMsCnQgtyO9B9YOwXf1Xp73ifaLIv-fa6knJFnz03JbJ5I5gAoQ/s1600/debian-logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;232&quot; data-original-width=&quot;480&quot; height=&quot;154&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsKUm5STou9Pqkw2Av_v17D5f7ez2dFmoptuM2NTX1vuGJRP3A1Se5PLuQMCZV8nfG73evQJJ_EUdO9IIlhVuUMsCnQgtyO9B9YOwXf1Xp73ifaLIv-fa6knJFnz03JbJ5I5gAoQ/s320/debian-logo.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanxue-it.blogspot.com/feeds/2528491712509705043/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/7389078/2528491712509705043' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2528491712509705043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7389078/posts/default/2528491712509705043'/><link rel='alternate' type='text/html' href='http://hanxue-it.blogspot.com/2019/01/debian-no-network-connection-even-after.html' title='Debian: no network connection even after restarting network manager'/><author><name>Hanxue</name><uri>http://www.blogger.com/profile/14117444242661786533</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsKUm5STou9Pqkw2Av_v17D5f7ez2dFmoptuM2NTX1vuGJRP3A1Se5PLuQMCZV8nfG73evQJJ_EUdO9IIlhVuUMsCnQgtyO9B9YOwXf1Xp73ifaLIv-fa6knJFnz03JbJ5I5gAoQ/s72-c/debian-logo.png" height="72" width="72"/><thr:total>1</thr:total></entry></feed>