A directory

Do not toss the front end, and salted fish have what difference

A directory
The preface
Three Node solutions for writing bash scripts
Four programming prepositions
5. Close Port
Delete files/folders
Seven Git operation
7.1 Git command is commonly used in work
7.2 Switching branches
Eight summary
9 References

The preface

Today, Jsliang got another kick out of work and opened the VIP channel:

  1. Automatically download Excel files
  2. Copy to the specified directory
  3. Perform multilingual import operations
  4. The resource to be importedgit pushGo up

Although it looks like a rough operation, there’s nothing to tell.

However, in the operation, it may be more complicated, such as the Git operation after only importing the resource:

  1. Add staging area:git add .
  2. Switch branches:git checkout -b <branch>
  3. Submit local repository:Git commit -m "feat "git commit -m "feat
  4. Submit a remote branch:git push --set-upstream origin <branch>

Of course, not only that, but you’ll also need to check that your build will pass after you add your multilingual resource…

So, all of this is just to draw out the operation of the bash instruction.

At work, you may encounter:

  • Git series operations
  • Close the occupied system port
  • Deletes the specified file/folder, etc

However, you can easily forget the instructions for these operations, or the instructions are too cumbersome, so Jsliang thought it would be easier to install them.

Three Node solutions for writing bash scripts

As for this solution, JSliang can’t be bothered, so it goes straight to ShellJS:

  • ShellJS – Unix shell commands for Node.js

If you think it is a little abrupt to directly go to the plan like this, I hope to have a reference and comparison, you can see:

  • Node.js is the ultimate solution for writing bash scripts

The author compared Node’s child_process API, ShellJS and ZX, and finally adopted ZX’s solution.

Of course, Jsliang is still using ShellJS for its work, so you don’t want to be tired of exploring similar libraries, so install ShellJS

  • Installation:npm i shelljs
  • Install TS and compile:npm i @types/shelljs -D

Installation complete, start tossing!

Four programming prepositions

To make the code less stinking and long.

After Jsliang wrote the article, he read the whole article more than 3 times, and compiled the repeated code and problems in the following section. Please read this chapter carefully before you copy the code

warn! please read the following carefully

The full directory is as follows. Please remember to create a new directory in advance:

Then repeat the code as follows:


import { inquirer } from '.. /base/inquirer'; import { Result } from '.. /base/interface'; // System operation import {sortCatalog} from '.. '. /base/file/sortDir'; import { deleteDir } from '.. /base/file/deleteDir'; // Multi-language import {downloadExcel} from './language/download'; import { importLanguage } from './language/import'; import { exportLanguage } from './language/export'; // Shell operation import {closePort} from '.. /base/shell/closePort'; import { gitCheckout } from '.. /base/shell/gitCheckout'; / / the problem recorder const answers = {q0: ' ', q1: ', q2: ', q3: "', q4:" ', q5: "', q6: ', q7: ', q8: ',}; Const common = (): void = bb0 {// Q0 {type: 'list', message: ', choices: [' public services ', 'multilanguage '],}, // q1 {type: 'list', message:' public services currently have: ', choices: Sort [' file ', 'close port', 'delete folders',' Git operation],}, / / q2 {type: "input", the message: 'need to sort the folder for? (absolute path)',}, / / q3 {type: ', choices: [' download ', 'import ',' export ',],}, // q4 {type: 'input', message: '(HTTP) resource download address?', default: 'https://www.kdocs.cn/l/sdwvJUKBzkK2', / / q5}, {type: 'input, the message: ',}, // q6 {type: 'input', message: 'the path you want to delete is? ',}, // q7 {type: 'list', message: 'what Git need support?' choices: [' switching branches', / / More...],}, / / q8 {type: 'inupt, message:' Git branch name? ',},]; Const answerList = [// Q0 - What services do you need? Any) => {answers.q0 = result.answer; switch (result.answer) {case 'public service ': questions[1](); break; case' multilanguage ': }}, // Q1 - Async (result: result, questions: Any) => {answers.q1 = result.answer; switch (result.answer) {case 'File sort ': questions[2](); break; case' Open port ': 'Git ': 'Git ': 'Git ': 'Git ': 'Git ': 'Git ': 'Git ': 'Git ': 'Git ': 'Git ': 'Git ': 'Git ': 'Git ': Async (result: result, _questions: any, prompt:) async (result: result, _questions: any, prompt:) any) => { answers.q2 = result.answer; const sortResult = await sortCatalog(result.answer); if (sortResult) { Console. log(' Sort successfully! '); prompts.complete();}}, // Q3 - What support do you need for the language async (result: result, questions: any, prompt: If (any) => {answers.q3 = result.answer; switch (result.answer) {if (any) => {answer.q3 = result.answer; Questions [4](); break; case 'exporting multilingual resources ': Const exportResult = await exportLanguage(); if (exportResult) {console.log(' Export successful! '); prompts.complete();} default: Async (result: result) => {answers.q4 = result.answer; const download = async (): Promise<any> => {const downloadResult = await downloadExcel (result.answer); if (downloadResult) {console.log(' Download successfully! '); Return true;}}; switch (answers.q3) {case 'Download multilingual resource ': await download(); break; case' Import multilingual resource ': Await download(); const importResult = await importLanguage(); if (importResult) {console.log(' import finished! ');} default: // Q5 - What port do you need to close? Async (result: prompt: any) => { answers.q5 = result.answer; const closeResult = await closePort(result.answer); if (closeResult) { Console. log(' closed successfully '); prompts.complete();}}, // Q6 - What path do you need to delete? any) => { answers.q6 = result.answer; const deleteResult = await deleteDir(result.answer); if (deleteResult) { Console. log(' delete successfully '); prompts.complete();}}, // Q7 - What support do you need for Git? If (any) => {answers.q7 = answers.answer; answer [8]();}, // Q8-git branch? any, prompts: any) => { answers.q8 = result.answer; const checkoutResult = await gitCheckout(result.answer); if (checkoutResult) { Console. log(' switchover successful '); prompts.complete();}},]; inquirer(questionList, answerList); }; export default common;


Export const questionList = {' public service ': {// q0 'file sort ': {// q1' folder to sort ': 'Work Work, / / q2},' close port: {/ / q1 'need to shut down the port' : 'Work Work, / / q5},' delete folders: {/ / q1 'need to delete the path: 'Work Work, / / q6},' Git operation: {/ / q1 'switching branches: {/ / q7' branch name ':' Work Work, / / q8},},}, 'multiple languages: {/ / q0' download multilingual resource: {/ / q3 'download address:' Work Work, / / q4}, 'import multi-language resources: {/ / q3' download address: 'Work Work, / / q4},' language resources are derived: {/ / q3 'export quantity of all resources: 'Work Work ', 'export single resource ': 'Work Work ',}},};

The following article states:

Update the SRC/common/index. Ts

Update the SRC/common/questionList. Ts

In this case, the partners do not need to operate, there are 3 places in this article have this description.

Also, in order to avoid reporting TypeScript errors when referencing and running code, the three new files are listed at the beginning:


import shell from 'shelljs';

export const deleteDir = async (path: string): Promise<boolean> => {


import shell from 'shelljs';

export const closePort = async (port: string): Promise<boolean> => {


import shell from 'shelljs'; /** * @name toggle branch * @description directive merge: ${branch} *. Git pull * @param {string} branch */ export const gitCheckout = (branch: string): boolean => { console.log(branch) };

In addition
commonUnder the
sortCatalog.tsMigration to
base/fileDirectory and rename it to

So, ready to go, start exporting!

5. Close Port

When you start some magic service, you will encounter a situation where the port is being used, and you will need to close the port:

  • To view the port occupancy:Netstat ano | findstr searches "port"
PS: F \ XXX > netstat ano | findstr searches "3001" TCP 33396 TCP LISTENING: 63001 TCP [::]:3001 [::]:0 Listening 33396
  • Termination of PID:Taskkill -f -pid PID number
PS F:\ XXX > taskkill -f -pid 33396 Success: Processes with PID 33396 have been terminated.

When it comes to the Node library, don’t do it yourself. Make it easy:

Update the SRC/common/index. Ts

Update the SRC/common/questionList. Ts

Then write ClosePort.ts:


import shell from 'shelljs'; export const closePort = async (port: string): Promise<boolean> => { await shell.exec(`netstat -ano | findstr :${port}`); // Windows will return a port inventory, you need to delete console.log(' I found the list above, please delete port: taskkill -f -pid PID number '); return await true; };

Note: The last one printed by Windows is PID number

Of course, 3001 May have several IP ports, so we are only prompting for the latter step, rather than closing all 3001 ports (which requires the user to do manually).

But that’s better than memorizing the instructions (Windows, Mac, etc.).

Execute NPM run jsliang with the following results:

This way we have encapsulated the closure of the port, because it is not a one-click complete closure, utility index to the ☆☆

Delete files/folders

In order to find out how quickly Windows can delete node_modules, Jsliang actually looked through the data and found three ways to delete files/folders:

  1. cmd.exe:rd /s /q <path>
  2. PowerShell:rd -r <path>
  3. Mac:rm -rf <path>

After a lot of personal experience, on a company desktop computer with 32GB of RAM and 500 SSDs, the delete operation through PowerShell was faster than the cmd.exe operation (don’t ask me why, it was faster, just personal experience, not scientific support).

Then look at ShellJS and see how it can be deleted:

  • ShellJS:rm()Delete the file,rm('rf', <path>)Delete folder

Of course! In the spirit of exploration, let’s look at how the source code is implemented:

  • Github: Shelljs-rm.js
function rmdirSyncRecursive(dir, force, fromSymlink) { // 1. Let files = fs.readdirSync(dir); for (var i = 0; i < files.length; I++) {// 1.2 Call fs.unlinkSync() to delete} // 2. Delete fs.rmDirSync (); }

Of course, some of the details are still well written, here will not be explained in detail, interested partners can click the above link to explore the source code.

So, let’s go with ShellJS! Replace it with a system command if you don’t feel comfortable.

Update the SRC/common/index. Ts

Update the SRC/common/questionList. Ts

Then start writing deletedir.ts:


import shell from 'shelljs'; export const deleteDir = async (path: string): Promise< Boolean > => {/** * cmd.exe: rd /s /q <path> * PowerShell: rd-r <path> * Mac: rm-rf <path> * ShellJS: Rm () deletes file, rm('rf', <path>) deletes folder */ await shell.rm('-rf', path); return true; };

Execute NPM run jsliang and print as follows:

Done! Call it a day! It is not clear which Node operation or system instruction is faster, so it is not clear which Node operation or system instruction is faster

Seven Git operation

So finally, it’s time for the big Git operation.

Surely some of you are just as lazy as Jsliang?

  • git add .
  • git commit -m "xxx"
  • git push

JSliang has even developed a specific VS Code plug-in:

Note: VS Code is also a volume, the update is too fast for my plugin to accept (to some extent, the latest VS Code doesn’t use this plugin), so my VS Code version is locked
v1.53.2When will you have time to update this plugin

In the VS Code plug-in, do a quick commit operation.

So in some general Git operations we still want to be encapsulated (no need to remember instructions, no need to click on a page, just let it run)

7.1 Git command is commonly used in work

JSLIANG is often used at work and has memorized the corresponding instructions:

  • git pull: pull code and merge automatically,jsliangWe’ll use it over heregit pull --rebase origin master, indicating that the remote branch is pulled and changes are made based on the branch
  • git checkout -b <newBranch>: Cut a new branch from the current branch
  • git branch -D <branch>: Deletes the specified branch by its name
  • git add <files>: Submit to staging area
  • git commit <description>: Commit to a local repository. If you have it in your warehouseeslintChecking and so on, highly recommendedgit commit -m "xxx" --no-verify(Sometimes I really don’t want to do any inspections)
  • git push: Commit to a remote library. Generally, the new branch operation isgit push -- set upstream origin <branch>
  • git cherry-pick <commitHash>: Submit the specified (commit) applies to other branches
  • git stash: Temporary contents. Stores the contents of the staging area onto the stack (multiple timesstashYou can do it multiple timespopOut)
  • git stash pop: Check out the content. willgit stashThe content of the
  • git reset --soft HEAD^: Rolls back the version and retains the content. thisHEAD^This is the previous version, which can also be written asHEAD~1(Commit ID)

It’s worth mentioning that JSliang has tried it before: a git worktree, which can modify multiple versions at the same time.

But because of the trouble (to remember the instructions), so useless

The same Git repository may need to modify multiple branches at the same time, or it may need to modify branch A based on branch B.

In this case, you can use git clone to copy a new repository, but if your repository is a bit large (a few gigabytes), it may be a bit troublesome.

So you have a git worktree with the following command:

Git worktree add... git worktree add... git worktree add... /jsliang ABC # git add [< option >] < path > [< commit >] # get help git worktree -h # git worktree list # complete worktree information # git Git worktree lock git worktree unlock git worktree move ABC... git worktree move ABC... Git worktree delete git worktree delete git worktree delete git worktree delete Git worktree prune git worktree prune

Common git worktree directives:

  • Cut out branches:git worktree add .. /jsliang abc
  • Common operation:git add .,git commit -m "xxx",git push
  • Close the branch:git worktree prune

And, of course, there’s the Git setup proxy

In scientific Internet use, sometimes Git does not work and a clone or push operation is as slow, so you need to set up a Git agent.

  • Set the agent
  1. Git config --global http.proxy address
  2. Git config --global https.proxy address
  • Cancel the agent
  1. git config --global --unset http.proxy
  2. git config --global --unset https.proxy
  • View the agent that has been set up
  1. git config --global --get http.proxy
  2. git config --global --get https.proxy

I take the science proxy software that I use now, set git config –global http.proxy, git fluency is improved a lot.

7.2 Switching branches

With that said, let’s do some real work. Let’s do a simple branch switch:

Update the SRC/common/index. Ts

Update the SRC/common/questionList. Ts

Then update gitCheckout.ts:


import shell from 'shelljs'; /** * @name toggle branch * @description directive merge: ${branch} *. Git pull * @param {string} branch */ export const gitCheckout = (branch: string): boolean => { if (! Shell. Which ('git')) {shell. Echo ('Error: Please install git first! '); shell.exit(1); } console.log(' Start switching branches: '); const checkoutResult = shell.exec(`git checkout ${branch}`); if (checkoutResult.code ! == 0) {shell. Echo ('Error: Failed to cut branch! '); shell.exit(1); } console.log(' Start pulling code, please wait: '); const pullResult = shell.exec('git pull'); const { stdout, stderr } = pullResult; if (pullResult.code === 0) { if (stdout.includes('from the remote, But no such ref was ____.')) {console.log(' Your branch is the latest '); } } else if (pullResult.code === 1) { if (stderr.includes('There is no tracking information for the current branch.')) { Console. log(' No remote branch '); } } return true; };

Then run: NPM run jsliang and enter the branch name following the command:

Since this is a random branch we entered, it indicates that the branch switch failed.

Of course, you can load more content into it according to the real business, so I won’t explain it in detail here, just to cast a brick to attract jade first

Eight summary

In fact, I have been condensing some work processes by summarizing bash instructions in recent two days, but I can’t think of a better project example for a while, so I didn’t explain them all. So, if you come across such a situation, please come and comment on it, and I sincerely hope to discuss with you.

So, about ShellJS let’s pave the way for a little bit, the back of Jsliang in life, work encountered some interesting knowledge points to add in ~

So, see you next time!

9 References

  • Github: ShellJS – Unix shell commands for Node.js
  • Nuggets: 👏 Nodejs Write Bash Script Ultimate Solution!
  • GitHub: Git worktree function and use
  • Use of git worktree
  • Git Worktree parallel development and testing
  • Government-enterprise cloud front-end team: How do I use Git at work
  • SegmentFault: Git slay: Develop tests in parallel using Git Worktree
  • Where to program: How Git uses proxies (VPNs)
  • Ruan Yi-feng: Cherry-pick

JSLIANG’s document library consists of
Liang Junrongusing
Creative Commons Attribute – Non-Commercial – Share the Same Way 4.0 International License AgreementPermission. Based on < br / >
https://github.com/LiangJunrong/document-libraryOn the creation of works. <br/> Use rights not authorized by this License Agreement can be obtained from [
https://creativecommons.org/l…] (