大衆へのコンソール。 明るい側に行く。 日常業務の自動化

日常的なタスクの自動化



はじめに



生産性やチームのリクルートに関係なく、車は常に高速になります。 人生の厳しい真実。 一方、同じアクションを何度も実行する場合は、マシンを苦しめないでください。 多くの時間、労力、エネルギーを要する単調なコマンドを入力するのではなく、 bash



(お気に入りのプログラミング言語)でスクリプトを作成し、毎回このスクリプトを呼び出します。 そして、スクリプトがその仕事をする間、宇宙船が私たちの宇宙の広がりを耕す方法について夢を見ることができます。



前回の記事では、 bash



プログラミングの基礎について説明しました。 今日は、習得した知識を実践します。



自動化計画



  1. クイックdiff



  2. Fast diff



    + Jira API
  3. クリーニング_dist



  4. 多数のリポジトリをアップ
  5. 多数のリポジトリのクローニング
  6. 便利なエイリアス


このリストには、1日に数回、または1時間に1回実行するタスクが含まれています。 一般に、日常的なプロセスの自動化は創造的で純粋に個人的なプロセスです。

あなたが思い付くことができるすべてを自動化することができます。 記事の最後に、自動化のための独自の計画があり、自動車が苦しくなることを願っています。 香り豊かなコーヒーを1杯飲んで、座ってください。 bash



を使用すると、自動化の世界に魅力的な旅ができます。



クイック差分



プロジェクトの作業ではGitを使用しますdiff



作成はかなり一般的なタスクです。 特定のブランチのdiff



を作成するには、次のコマンドを実行する必要があります。



 git diff origin/master origin/<branch-name> > "${HOME}/diff/diff-<branch-name>.diff"
      
      





<branch-name>



diff



を作成するブランチの名前



このアプローチの欠点



  1. コマンドを入力する必要があるたびに
  2. 採用プロセス中のエラーの可能性が高い
  3. 覚えにくい


これらの欠点はbash



で簡単に解決できます。 理想的には、すべてが次のように機能するはずです。

  1. チームを入力しました
  2. 彼らは彼女に枝の名前を与えました
  3. 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
view raw fast_diff.sh hosted with ❤ by GitHub


これで、長いコマンド行ではなく、キーボードで./fast_diff.sh <branch-name>



と入力するだけです。 ブランチの名前を指定するのを忘れた場合、このスクリプトはこれを親切に知らせてくれます。



最後のタッチ



やめて しかし、チームの最終的な外観についてはどうでしょう。 実際、現在の形式では、このスクリプトはあまり便利ではありません。スクリプトが配置されているディレクトリに関連付けられています。



実行可能ファイルへの相対/絶対パスを毎回書き込むのではなく、実行可能ファイルに対して個別のコマンドを作成する方法をより詳細に検討してみましょう。



ホームディレクトリ( ~



)の各ユーザーには、 bin



サブディレクトリがあります。 ない場合は、作成できます。 実行可能ファイルを保存できます。 便利なのは、そのようなファイルは名前でアクセスでき、それらへの相対/絶対パスを指定する必要がないということです。 このディレクトリに、 diff



を作成するgdd



ファイルを配置します。



 #!/bin/bash "${HOME}/htdocs/rybka/tools/fast_diff.sh" "$@"
      
      





いくつかの重要なポイント:



  1. ファイルは拡張子を指定するために受け入れられません。
  2. 属性x (chmod +x <filename>)



    は、ファイルに対して明示的に指定する必要がありますx (chmod +x <filename>)





  3. 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も必要です。



決定アルゴリズム



  1. スクリプトを呼び出します
  2. タスクid



    を渡します
  3. タスクid



    転送されない場合、ユーザーにメッセージを表示します
  4. すべてが正しい場合は、 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
view raw fast_diff_v2.sh hosted with ❤ by GitHub


お気づきかもしれませんが、ブランチ名を指定する必要はありません。 gitコマンドを使用した簡単な操作を使用して取得します。



 branch=$(git rev-parse --abbrev-ref HEAD)
      
      





クリーニング_dist



はじめに、 _dist



ディレクトリが何を担当_dist



ているかを把握しましょう。 これは、ビルドシステムの起動後( GruntGulpなど)、 CSS



JavaScript



ファイル、あらゆる種類のテンプレート( Jade / PugHandlebarsなど)およびその他のファイルが置かれる場所です。 このディレクトリは_dist



と呼ばれる_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



ディレクトリを削除する必要がある特定のトピックを指定する方法はありません。



決定アルゴリズム



  1. スクリプトを呼び出します
  2. トピック名が転送されていない場合は、すべてのトピックの_dist



    ディレクトリを削除します
  3. トピック名が転送された場合、特定のトピックの_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 "$@"
view raw clean_dist.sh hosted with ❤ by GitHub


多数のリポジトリをアップ

多数のリポジトリをアップ

大規模なプロジェクトで作業していると想像してください。 このプロジェクトには、開発していないが最新の状態を維持するために必要なサードパーティのリポジトリ用に予約されたディレクトリがあります。 もちろん、これらのリポジトリが2つまたは3つある場合、これはそれほど大きな問題ではありません。 ここで私は主張しますが。 そして、あなたがそのようなリポジトリ10-15を持っているなら、この数字は絶えず成長しています。 その結果、あなたは彼らをフォローする時間がないか、サポートに不釣合いな時間を費やすことができません。 このタスクを自動化しないのはなぜですか。



決定アルゴリズム



  1. リポジトリのあるディレクトリに移動します
  2. リポジトリがmaster



    ブランチにあることを確認します
  3. リポジトリがmaster



    ブランチにない場合、 git checkout



    実行します
  4. 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 "$@"
view raw up_repo.sh hosted with ❤ by GitHub


多数のリポジトリのクローニング



このタスクは、以前の自動化ポイントと密接に関連しています。 エンドユーザーが実際に前のチームを使用できるようにするには、 bash/core/vendors



に配置されるサードパーティリポジトリのセットを提供する必要があります。 npmモジュールと同様に、このリポジトリのセットはメインリポジトリに付属しません。 ユーザーが行う必要があるのは、コマンドを実行し、リポジトリが複製されるまで待つことだけです。



決定アルゴリズム



  1. リポジトリのリストは配列として与えられます
  2. この配列でループを開始します
  3. 1つのベンダーに複数のリポジトリがある場合は特に注意を払います
  4. 追加のチェックを実施します
  5. 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 "$@"
view raw clone_vendors.sh hosted with ❤ by GitHub


便利なエイリアス



読者にいくつか質問があります。 自分に正直に答えなければなりません。 このコマンドはどのくらいの頻度で使用しますか?



 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 '
GitHub によって❤でホストされいる生のaliases.shを表示する


設定したエイリアスを確認するには、パラメータなしでalias



コマンドを実行するだけです。



エイリアスを置く場所



ほとんどの場合、ユーザーのホームディレクトリにある.bashrc



、そのような目的に使用されます。 .gitconfig



というファイルもあります。このファイルには、 git



ためのエイリアスを追加できます。



夜間にエイリアスを変更しないでください



エイリアスは強力なツールです。 パスワードの場合と同様、ここでのみ。 エイリアスを夜遅く変更しないでください。 ある晴れた夜、エイリアスの1つを変更して忘れました。 翌日、何も機能しなかった理由を解明するために半日費やしました。



結論の代わりに



bash



プログラミングの基本を理解し始めるとすぐに、私を訪問した最初の考えは「やめなさい、これはシステム管理者にとってもっと必要なことです...」。 しかし同時に、私は日常の日常業務から何らかの形で自分を救うためにこの知識が必要であることに気付きました。 システム管理者だけでなく、この知識が必要であると自信を持って言えます。 これらは、少なくとも何らかの形でリモートサーバーとやり取りするか、 OS *nix



ようなシステムで実行するOS *nix



ます。 Windows OSで作業するユーザーにとっても、この知識は役に立ちます( Windows上のUbuntu、WindowsおよびUbuntuの相互運用性 に関するBash )。 最も単純な場合、スクリプトはファイルに書き込まれたシステムコマンドの単純なリストにすぎません。 このようなファイルを使用すると、就業時間が短縮され、日常的なタスクを手動で実行する必要がなくなります。



例で使用されたいくつかのbash



機能に関する便利なリンク:



  1. 入力/出力のリダイレクト
  2. 機能
  3. 配列
  4. 二重括弧
  5. 連鎖チーム(コンベヤー)
  6. 完了コードと完了コード
  7. エイリアス
  8. $ PATH変数にパスを正しく追加する方法


以上です。 ご清聴ありがとうございました。 最後まで読んでくれた人、ありがとう。



All Articles