
はじめに
生産性やチームのリクルートに関係なく、車は常に高速になります。 人生の厳しい真実。 一方、同じアクションを何度も実行する場合は、マシンを苦しめないでください。 多くの時間、労力、エネルギーを要する単調なコマンドを入力するのではなく、
bash
(お気に入りのプログラミング言語)でスクリプトを作成し、毎回このスクリプトを呼び出します。 そして、スクリプトがその仕事をする間、宇宙船が私たちの宇宙の広がりを耕す方法について夢を見ることができます。
前回の
記事では、
bash
プログラミングの基礎について説明しました。 今日は、習得した知識を実践します。
自動化計画
- クイック
diff
- Fast
diff
+ Jira API - クリーニング
_dist
- 多数のリポジトリをアップ
- 多数のリポジトリのクローニング
- 便利なエイリアス
このリストには、1日に数回、または1時間に1回実行するタスクが含まれています。 一般に、日常的なプロセスの自動化は創造的で純粋に個人的なプロセスです。
あなたが思い付くことができるすべてを自動化することができます。 記事の最後に、自動化のための独自の計画があり、自動車が苦しくなることを願っています。 香り豊かなコーヒーを1杯飲んで、座ってください。
bash
を使用すると、自動化の世界に魅力的な旅ができます。
クイック差分
プロジェクトの作業では
Gitを使用し
ます 。
diff
作成はかなり一般的なタスクです。 特定のブランチの
diff
を作成するには、次のコマンドを実行する必要があります。
git diff origin/master origin/<branch-name> > "${HOME}/diff/diff-<branch-name>.diff"
<branch-name>
diff
を作成するブランチの名前
このアプローチの欠点
- コマンドを入力する必要があるたびに
- 採用プロセス中のエラーの可能性が高い
- 覚えにくい
これらの欠点は
bash
で簡単に解決できます。 理想的には、すべてが次のように機能するはずです。
- チームを入力しました
- 彼らは彼女に枝の名前を与えました
diff
チームの最終ビュー
gdd <branch-name>
自動化
| #!/bin/bash |
| |
| # create diff for current branch and puts it in the file |
| # ./fast_diff.sh <branch> - how this script should called |
| |
| PATH_TO_DIFF_DIR="${HOME}/diff/" |
| FILE_PREFIX="diff-" |
| FILE_EXTENTION=".diff" |
| |
| branch="$1" |
| |
| # if "$branch" is empty |
| if [[ -z "$branch" ]] |
| then |
| echo "Enter the branch name" |
| exit 0 |
| else |
| path="${PATH_TO_DIFF_DIR}${FILE_PREFIX}${branch}${FILE_EXTENTION}" |
| git diff origin/master origin/"$branch" > "$path" |
| fi |
これで、長いコマンド行ではなく、キーボードで
./fast_diff.sh <branch-name>
と入力するだけです。 ブランチの名前を指定するのを忘れた場合、このスクリプトはこれを親切に知らせてくれます。
最後のタッチ
やめて しかし、チームの最終的な外観についてはどうでしょう。 実際、現在の形式では、このスクリプトはあまり便利ではありません。スクリプトが配置されているディレクトリに関連付けられています。
実行可能ファイルへの相対/絶対パスを毎回書き込むのではなく、実行可能ファイルに対して個別のコマンドを作成する方法をより詳細に検討してみましょう。
ホームディレクトリ(
~
)の各ユーザーには、
bin
サブディレクトリがあります。 ない場合は、作成できます。 実行可能ファイルを保存できます。 便利なのは、そのようなファイルは名前でアクセスでき、それらへの相対/絶対パスを指定する必要がないということです。 このディレクトリに、
diff
を作成する
gdd
ファイルを配置します。
いくつかの重要なポイント:- ファイルは拡張子を指定するために受け入れられません。
- 属性
x (chmod +x <filename>)
は、ファイルに対して明示的に指定する必要がありますx (chmod +x <filename>)
。
bin
ディレクトリが$PATH
変数にない場合は、明示的にPATH="${PATH}:${HOME}/bin"
に追加する必要があります。
このファイルを使用可能にするには、ターミナルを再起動します。
diff
を作成するには、次のコマンドを実行するだけです:
gdd <branch-name>
コマンドごとに
bin
ディレクトリに個別のファイルを常に作成するのはあまり便利ではありません。 シンボリックリンクを使用してこれを最適化できます。
ln -s "${HOME}/htdocs/rybka/tools/fast_diff.sh" gdd
Fast diff + Jira API
Jiraタスクマネージャーまたは作業で
APIを提供する他のタスクマネージャーを使用する場合は、さらに先に進むことができます。 たとえば、Jira APIを使用して、
diff
を特定のタスクに添付できます。 これには
cURLも必要です。
決定アルゴリズム
- スクリプトを呼び出します
- タスク
id
を渡します - タスク
id
転送されない場合、ユーザーにメッセージを表示します - すべてが正しい場合は、
diff
を生成してタスクに添付します
チームの最終ビュー
gdd_jira <issue_id>
自動化
| #!/bin/bash |
| |
| PATH_TO_DIFF_DIR="${HOME}/diff/" |
| FILE_EXTENTION=".diff" |
| |
| USER_NAME="<user_name>" |
| USER_PASSWORD="<user_password>" |
| PROJECT_NAME="<project_name>" |
| |
| # if "$1" is empty |
| if [ -z "$1" ] |
| then |
| echo "Please, specify an issue ID" |
| exit 0 |
| fi |
| |
| issue_id="$1" |
| branch=$(git rev-parse --abbrev-ref HEAD) |
| |
| # Get the first line of git remote output and cut a path to repository |
| repository=$(git remote -v | head -n1 | sed "s/^origin.*\/\(.*\)\.git\s(.*)/\1/") |
| file_name="${branch}-${repository}${FILE_EXTENTION}" |
| |
| # path to diff directory with <filename>.diff |
| path_to_diff="${PATH_TO_DIFF_DIR}${file_name}" |
| |
| diffMaster() { |
| git diff "origin/master origin/${branch}" > "$path_to_diff" |
| } |
| |
| attachDiff() { |
| curl -D -u "${USER_NAME}":"${USER_PASSWORD}" -X POST -H "X-Atlassian-Token: no-check" -F "file=@${path_to_diff};type=text/x-diff" "https://jira.${PROJECT_NAME}.com/rest/api/2/issue/${issue_id}/attachments" |
| } |
| |
| diffMaster && attachDiff |
| |
| # Usage: cd <repo_name> && fast_diff_v2.sh <issue_id> |
| # <issue_id> should include your company prefix (ABC, XYZ, XX, etc.) |
| # At instance, "./fast_diff_v2.sh XYZ-135" will try to attach diff to |
| # https://jira.<project_name>.com/browse/XYZ-135 |
お気づきかもしれませんが、ブランチ名を指定する必要はありません。 gitコマンドを使用した簡単な操作を使用して取得します。
branch=$(git rev-parse --abbrev-ref HEAD)
クリーニング_dist
はじめに、
_dist
ディレクトリが何を担当
_dist
ているかを把握しましょう。 これは、ビルドシステムの起動後(
Grunt 、
Gulpなど)、
CSS
、
JavaScript
ファイル、あらゆる種類のテンプレート(
Jade / Pug 、
Handlebarsなど)およびその他のファイルが置かれる場所です。 このディレクトリは
_dist
と呼ばれる
_dist
はありません。 バリエーションが可能です。

プロジェクトの1つにGruntを使用します。 多くの場合、私たちのチームは、Gruntが一部のファイルの変更に常に気付かないという問題に遭遇します(問題は主に
Lessファイルにあります)。 この状況を修正するには、トピックの1つまたはすべてのトピックの
_dist
ディレクトリを一度にクリアする必要があります。 はい、この問題はGruntの助けを借りて解決できます。 このディレクトリをいつでも手動で削除することもできます。 しかし、
bash
の場合ほど効率的で便利ではありません。 これらのディレクトリの数(
_dist
)は1
_dist
2
_dist
、10でも20でもありません。 たくさんあります。 スクリプトの主な要件は、余分なラッパーや依存関係を不必要に使用しないことです。
bash
を使用しないオプションを検討してください。 この問題を解決するために、シェルのすべての力を使用します。
find <path-to-themes> -type d -name "_dist" | xargs rm -rfv
<path-to-themes>
-すべてのトピックが置かれているディレクトリへのパス
このアプローチの欠点は、
diff
を作成するタスクの場合に引用したものとほぼ同じです。 さらに、この場合、
_dist
ディレクトリを削除する必要がある特定のトピックを指定する方法はありません。
決定アルゴリズム
- スクリプトを呼び出します
- トピック名が転送されていない場合は、すべてのトピックの
_dist
ディレクトリを削除します - トピック名が転送された場合、特定のトピックの
_dist
ディレクトリを削除します
チームの最終ビュー
clean_dist [<theme_name>]
自動化
| #!/bin/bash |
| |
| # clean_dist.sh - clean dist for current theme |
| # ./clean_dist.sh - clean all directories with dists |
| # ./clean_dist.sh <theme> - clean <theme> dist |
| |
| |
| cleanDist() { |
| theme="$1" |
| DIST_NAME="_dist" |
| REPO_NAME="terminalForCoder__WSD" |
| PATH_TO_CORE="${HOME}/${REPO_NAME}/bash/core" |
| |
| PATH_TO_ASSETS="${PATH_TO_CORE}/assets" |
| |
| # if "${PATH_TO_CORE}" is not exist |
| # show info message |
| if [[ ! -e "${PATH_TO_CORE}" ]] |
| then |
| echo "Cannot find ${PATH_TO_CORE}" |
| echo "Try to edit REPO_NAME in ${0}" |
| exit 0 |
| fi |
| |
| # if $1 == "" clean all _dist in each theme |
| if [[ -z "$theme" ]] |
| then |
| path_to_dist="$PATH_TO_ASSETS" |
| else |
| path_to_dist="${PATH_TO_ASSETS}/${theme}" |
| fi |
| |
| if [[ -n $(find "$path_to_dist" -type d -name "$DIST_NAME") ]] |
| then |
| # do clean stuff |
| find "$path_to_dist" -type d -name "$DIST_NAME" | xargs rm -rfv |
| echo "Dist of ${theme} has already deleted: ${path_to_dist}" |
| else |
| echo "Cannot find ${DIST_NAME} in ${theme}" |
| fi |
| } |
| |
| cleanDist "$@" |
多数のリポジトリをアップ

大規模なプロジェクトで作業していると想像してください。 このプロジェクトには、開発していないが最新の状態を維持するために必要なサードパーティのリポジトリ用に予約されたディレクトリがあります。 もちろん、これらのリポジトリが2つまたは3つある場合、これはそれほど大きな問題ではありません。 ここで私は主張しますが。 そして、あなたがそのようなリポジトリ10-15を持っているなら、この数字は絶えず成長しています。 その結果、あなたは彼らをフォローする時間がないか、サポートに不釣合いな時間を費やすことができません。 このタスクを自動化しないのはなぜですか。
決定アルゴリズム
- リポジトリのあるディレクトリに移動します
- リポジトリが
master
ブランチにあることを確認します - リポジトリが
master
ブランチにない場合、 git checkout
実行します git pull
重要なポイント 。 リポジトリが
master
ブランチ上にある場合でも、それが最新であることを確認することはできません。 これに基づいて、とにかく
git pull
を行います。
チームの最終ビュー
up_repo
自動化
| #!/bin/bash |
| |
| # up_repo.sh - check repositories in core/vendor |
| # find all directories that included .git |
| # If any repo hasn't switched on master branch |
| # than git checkout master && git branch && git pull |
| # else git branch && git pull |
| |
| # get list of repositories |
| findRepo() { |
| REPO_NAME="terminalForCoder__WSD" |
| PATH_TO_VENDORS_REPO="${HOME}/${REPO_NAME}/bash/core/vendors/" |
| |
| # find all git repositories in $PATH_TO_VENDORS_REPO |
| # filter by /.git |
| |
| if [[ -e "$PATH_TO_VENDORS_REPO" ]] |
| then |
| r=$(find "$PATH_TO_VENDORS_REPO" -name .git | xargs | sed "s/\\/.git//g") |
| else |
| echo "Cannot find ${PATH_TO_VENDORS_REPO}" |
| echo "Try to edit REPO_NAME in ${0}" |
| exit 0 |
| fi |
| |
| # do check repositories stuff |
| checkBranch $r |
| } |
| |
| # do check repositories stuff |
| checkBranch() { |
| BRANCH="master" |
| CHECK_BRANCH="* master" |
| |
| # $i is an item in $r |
| for i in "$@" |
| do |
| # get current branch name |
| b=$(cd "$i" && git branch | grep \*) |
| echo "repo: ${i}" |
| echo "current brunch: ${b}" |
| |
| # check branch |
| if [[ "$b" != "$CHECK_BRANCH" ]] |
| then |
| echo "!Error! ${i} is not on ${BRANCH} branch" |
| echo "Current branch is ${b}" |
| echo "Checkout to ${BRANCH} and do git pull stuff for ${i}" |
| cd "$i" && git checkout "$BRANCH" && git branch && git pull origin "$BRANCH" |
| echo "" |
| else |
| echo "Do git pull stuff for ${i}" |
| cd "$i" && git branch && git pull origin "$BRANCH" |
| echo "" |
| fi |
| done |
| echo "Done. Congratulation, you win!" |
| } |
| |
| findRepo "$@" |
多数のリポジトリのクローニング
このタスクは、以前の自動化ポイントと密接に関連しています。 エンドユーザーが実際に前のチームを使用できるようにするには、
bash/core/vendors
に配置されるサードパーティリポジトリのセットを提供する必要があります。 npmモジュールと同様に、このリポジトリのセットはメインリポジトリに付属しません。 ユーザーが行う必要があるのは、コマンドを実行し、リポジトリが複製されるまで待つことだけです。
決定アルゴリズム
- リポジトリのリストは配列として与えられます
- この配列でループを開始します
- 1つのベンダーに複数のリポジトリがある場合は特に注意を払います
- 追加のチェックを実施します
git clone
実行する
チームの最終ビュー
clone_repo
自動化
| #!/bin/bash |
| # clone vendors repositories to ./core/vendors |
| REPO_NAME="terminalForCoder__WSD" |
| PATH_TO_CORE="${HOME}/${REPO_NAME}/bash/core" |
| PATH_TO_VENDORS_REPO="${HOME}/${REPO_NAME}/vendors" |
| |
| # array with repositories |
| repositories=( "https://github.com/larscmagnusson/CSS3MultiColumn.git" "https://github.com/tc39/test262.git" "https://github.com/postcss/postcss" "https://github.com/webpack/webpack" "https://github.com/var-bin/spriteFactory.git" "https://github.com/var-bin/backbone-training.git" "https://github.com/var-bin/flex-grid-framework.git" "https://github.com/var-bin/BrandButtons.git" "https://github.com/var-bin/less-easings.git" ) |
| |
| i=0 # start el |
| repositories_count=${#repositories[@]} # array size |
| |
| cloneVendors() { |
| # if "${PATH_TO_CORE}" is not exist |
| # show info message |
| if [[ ! -e "${PATH_TO_CORE}" ]] |
| then |
| echo "Cannot find ${PATH_TO_CORE}" |
| echo "Try to edit REPO_NAME in ${0}" |
| exit 0 |
| fi |
| |
| # if "${PATH_TO_VENDORS_REPO}" is not exist |
| # create "${PATH_TO_VENDORS_REPO}" directory |
| if [[ ! -e "${PATH_TO_VENDORS_REPO}" ]] |
| then |
| mkdir "${PATH_TO_VENDORS_REPO}" |
| fi |
| |
| while [ "$i" -lt "$repositories_count" ] |
| do |
| # Get vendor name |
| vendor=$(echo ${repositories[$i]} | sed "s/https\:\/\/github\.com\/*//g" | sed "s/\/.*//g") |
| vendor_repo_name=$(echo ${repositories[$i]} | sed "s/https\:\/\/github\.com\/.*\///g" | sed "s/\.git//g") |
| |
| # if "${PATH_TO_VENDORS_REPO}/${vendor}" is directory |
| # go to directory and do git clone stuff |
| if [[ -d "${PATH_TO_VENDORS_REPO}/${vendor}" ]] |
| then |
| echo "Directory ${PATH_TO_VENDORS_REPO}/${vendor} is exist" |
| |
| if [[ ! -e "${PATH_TO_VENDORS_REPO}/${vendor}/${vendor_repo_name}" ]] |
| then |
| echo "Repository: ${repositories[$i]} is clonning" |
| cd "${PATH_TO_VENDORS_REPO}/${vendor}" && git clone ${repositories[$i]} |
| else |
| echo "Repository ${PATH_TO_VENDORS_REPO}/${vendor}/${vendor_repo_name} is exist" |
| echo "" |
| fi |
| else |
| # create directory "${PATH_TO_VENDORS_REPO}/${vendor}" |
| # go to directory and do git clone stuff |
| echo "Create directory: ${PATH_TO_VENDORS_REPO}/${vendor}" |
| mkdir "${PATH_TO_VENDORS_REPO}/${vendor}" |
| |
| echo "Repository: ${repositories[$i]} is clonning" |
| cd "${PATH_TO_VENDORS_REPO}/${vendor}" && git clone ${repositories[$i]} |
| fi |
| i=$((i + 1)) # i++ |
| done |
| } |
| |
| cloneVendors "$@" |
便利なエイリアス
読者にいくつか質問があります。 自分に正直に答えなければなりません。 このコマンドはどのくらいの頻度で使用しますか?
git branch
このチームはどうですか?
git status
しかし、このチーム?
git push origin <branch-name>
このチームはどうですか?
ps aux | grep <user-name>
そうです、このリストは無限に続くことができ、誰もが自分のものを持っています。 そして、予想外に、洞察が私たちにやってくる:

そうだね。 頻繁に使用するチームの場合は、エイリアスを作成します。 ここに、私が使用しているエイリアスの小さなリストを示します。
| alias gst='git status' |
| alias gf='git fetch' |
| alias gm='git merge' |
| alias gd='git diff' |
| alias gb='git branch' |
| alias gbm='git branch --merged' |
| alias gcm='git commit -m' |
| alias gp='git push origin' |
| alias gbd='git branch -D' |
| alias gshorth='git log -p -2' |
| alias gch='git checkout' |
| alias grntds='./grunt deploySync' |
| alias grntd='./grunt deploy' |
| alias ghide='git stash' |
| alias gshow='git stash pop' |
| alias gsl='git stash list' |
| alias myps='ps aux | grep rybka' |
| エイリアス gmom = ' git merge origin / master ' |
| エイリアス gad = ' git add ' |
| エイリアス grm = ' git rm ' |
設定したエイリアスを確認するには、パラメータなしで
alias
コマンドを実行するだけです。
エイリアスを置く場所
ほとんどの場合、ユーザーのホームディレクトリにある
.bashrc
、そのような目的に使用されます。
.gitconfig
というファイルもあります。このファイルには、
git
ためのエイリアスを追加できます。
夜間にエイリアスを変更しないでください
エイリアスは強力なツールです。 パスワードの場合と同様、ここでのみ。 エイリアスを夜遅く変更しないでください。 ある晴れた夜、エイリアスの1つを変更して忘れました。 翌日、何も機能しなかった理由を解明するために半日費やしました。
結論の代わりに
bash
プログラミングの基本を理解し始めるとすぐに、私を訪問した最初の考えは「やめなさい、これはシステム管理者にとってもっと必要なことです...」。 しかし同時に、私は日常の日常業務から何らかの形で自分を救うためにこの知識が必要であることに気付きました。 システム管理者だけでなく、この知識が必要であると自信を持って言えます。 これらは、少なくとも何らかの形でリモートサーバーとやり取りするか、
OS *nix
ようなシステムで実行する
OS *nix
ます。 Windows OSで作業するユーザーにとっても、この知識は役に立ちます(
Windows上のUbuntu、Windows 、
およびUbuntuの相互運用性 に関するBash )。 最も単純な場合、スクリプトはファイルに書き込まれたシステムコマンドの単純なリストにすぎません。 このようなファイルを使用すると、就業時間が短縮され、日常的なタスクを手動で実行する必要がなくなります。
例で使用されたいくつかの
bash
機能に関する便利なリンク:
- 入力/出力のリダイレクト
- 機能
- 配列
- 二重括弧
- 連鎖チーム(コンベヤー)
- 完了コードと完了コード
- エイリアス
- $ PATH変数にパスを正しく追加する方法
以上です。 ご清聴ありがとうございました。 最後まで読んでくれた人、ありがとう。