インストール - Bash
ナビゲーションに移動
検索に移動
概要
Bashは、GNUプロジェクトのシェル(Bourne Again SHell)である。
Kornシェル(ksh)やCシェル(csh)の便利な機能を取り入れたsh互換のシェルである。
IEEE POSIX P1003.2 / ISO 9945.2 Shell and Tools規格に準拠したシェルであり、プログラミングと対話的な使用の両方において、shよりも機能的に向上している。
また、ほとんどのshスクリプトはBashでそのまま実行することができる。
Bashが提供する主な機能を、以下に示す。
- コマンドラインの編集。
- コマンド履歴のサイズの変更。
- ジョブの制御。
- シェル関数とエイリアス機能。
- サイズ無制限のインデックス付き配列。
- 2から64までの任意の基数の整数演算。
Bashのインストール
パッケージ管理システムからインストール
パッケージ管理システムからBashをインストールする。
# RHEL sudo dnf install bash # SUSE sudo zypper install bash # Raspberry Pi sudo apt install bash
ソースコードからインストール
Bashのビルドに必要な依存関係のライブラリをインストールする。
# RHEL sudo dnf install ncurses-devel # SUSE sudo zypper install ncurses-devel # Raspberry Pi sudo apt install libncurses-dev
Bashの公式Webサイトから、Bashのソースコードをダウンロードする。
tar xf bash-<バージョン名>.tar.xz cd bash-<バージョン名>
次に、Bashをビルドおよびインストールする。
mkdir build && cd build ../configure --prefix=<Bashのインストールディレクトリ> \ --with-installed-readline --with-included-gettext --enable-array-variables --enable-multibyte \ --enable-job-control --enable-debugger --enable-brace-expansion --enable-arith-for-command \ --enable-history --enable-progcomp --enable-alias --enable-help-builtin make -j $(nproc) make install
Bashの使用
Bashを利用可能なシェル一覧に追加する。
ここに追加することで、chshコマンドでシェルの変更が可能となる。
echo "/<Bashのインストールディレクトリ>/bin/bash" | sudo tee -a /etc/shells
次に、ユーザのシェルを変更する。(コマンドを実行するとパスワードの入力が必要となる)
chsh -s /<Bashのインストールディレクトリ>/bin/bash
再ログインまたはPCを再起動する。
コマンドの履歴を保存しない
まず、~/.bash_historyファイルを削除する。
rm -rf ~/.bash_history
次に、メモリ上に残っているコマンド履歴を削除する。
history -c
~/.bashrcファイルに以下に示す設定を追記する。
vi ~/.bashrc
export HISTFILESIZE=0 export HISTSIZE=0 unset HISTFILE
設定を反映させるため、再ログインまたはPCを再起動する。
Bashの設定例
~/.bashrcファイルを作成して、以下のような設定を記述する。
# ~/.bashrcファイル
# Ctrl+Dでシェルを終了しない
set -o ignoreeof
# 既存のファイルをリダイレクトで上書きしない
set -o noclobber
# ディレクトリ名だけで実行する時、cdコマンドの引数で指定したものとして実行する
shopt -s autocd
# コマンドの重複を履歴に残さない
export HISTCONTROL=ignoredups
# 空白から始めたコマンドを無視
export HISTCONTROL=ignorespace
# コマンド履歴に残さないコマンド群
HISTTIMEFORMAT='%Y%m%d %T ';
export HISTTIMEFORMAT
# エイリアスの設定
alias cd='cd -P'
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -iv'
alias ls='ls -hlF --color=auto'
alias cat='cat -n'
alias less='less -n'
alias clear='clear && echo -en "\e[3J"'
alias en='LANG=C LANGUAGE=C LC_ALL=C'
alias lgrep='ls -ahlF | grep'
alias igrep='sudo zypper search -i --detail'
alias repoclean='sudo zypper clean -a && sudo zypper --gpg-auto-import-keys refresh && sudo zypper refresh'
alias nano='nano -lmS'
alias snano='sudo nano -lmS'
alias skate='kdesu /usr/bin/kate'
alias startnw=' sudo systemctl stop wickedd wicked; sudo systemctl start NetworkManager'
alias startwicked=' sudo systemctl stop NetworkManager; sudo systemctl start wickedd wicked'
alias kde=' echo <パスワード> | sudo -S systemctl restart graphical.target'
alias gnome=' echo <パスワード> | sudo -S systemctl restart graphical.target'
alias udesktop='update-desktop-database $HOME/.local/share/applications'
alias uoff='dbus-send --print-reply=literal --system --dest=org.freedesktop.login1 /org/freedesktop/login1 "org.freedesktop.login1.Manager.PowerOff" boolean:true' # シャットダウン
alias ureboot='dbus-send --print-reply=literal --system --dest=org.freedesktop.login1 /org/freedesktop/login1 "org.freedesktop.login1.Manager.Reboot" boolean:true' # 再起動
# KDE Plasmaの再起動
alias plasma='/usr/bin/kquitapp5 plasmashell; plasmashell > /dev/null 2>&1 & disown; sleep 2; exit'
#alias plasma="killall plasmashell; plasmashell > /dev/null 2>&1 & disown"
# GNOMEの再起動
alias gshell='killall -3 gnome-shell > /dev/null 2>&1 & disown; sleep 2; exit'
# VS Codeをスーパーユーザ権限で起動
alias scode='code --user-data-dir='<VSCodeのプロジェクトディレクトリ>''
# SUSEの情報を出力
alias suse='cat /etc/SUSE-brand'
# 各SSHの接続
alias sshpi='ssh <ユーザ名>@<ホスト名またはIPアドレス> -p <ポート番号> -i <暗号鍵のフルパス名>' # Raspberry Pi向けSSH接続の設定
# KVMの起動と停止
alias startkvm='sudo systemctl restart libvirtd'
alias stopkvm='sudo systemctl stop libvirtd && sudo systemctl stop libvirtd.socket && sudo systemctl stop libvirtd-admin.socket && sudo systemctl stop libvirtd-ro.socket'
# FreeRDPをインストールしている場合
alias rwin10='/<FreeRDPのインストールディレクトリ>/bin/xfreerdp /u:<仮想マシンのユーザ名> /p:<パスワード> /w:1600 /h:900 /sound:latency:400 /drive:suse,<共有するディレクトリ> /v:192.168.122.130'
# SUSEが仮想マシンの場合
alias mhgfs='sudo vmhgfs-fuse -o allow_other .host:/Common /mnt/hgfs'
alias uhgfs='sudo fusermount -u /mnt/hgfs'
# コマンド履歴に残さないコマンド群
## SUSEがホストの場合
export HISTIGNORE="fg*:bg*:history*:cd*:ls*:cat*:less*:more*:grep*:lgrep*:igrep*:startkvm:stopkvm:repoclean*:suse:which*:clear:man*:repoclean:startx*:exit:"
## SUSEが仮想マシンの場合
export HISTIGNORE="fg*:bg*:history*:cd*:ls*:cat*:less*:more*:grep*:lgrep*:igrep*:startkvm:stopkvm:repoclean*:suse:which*:clear:man*:repoclean:startx*:exit:mhgfs:uhgfs"
# プロンプトの表示形式
PS1='\e[0;31m\u\e[0m@\e[0;32m\h\e[0m(\t) [Path \w] \n> '
# 変数FIGNOREのカスタマイズ
# ディレクトリ名およびファイル名を設定する場合、補完対象から除外される
export FIGNORE=.svn:${FIGNORE}
# mkdirとcdを同時実行
function mkcd()
{
if [ "$#" -eq 0 ]; then
echo "Too few arguments!"
elif [ "$#" -eq 1 ]; then
if [ -d $1 ]; then
echo "$1 already exists!"
cd $1
else
mkdir -p $1 && cd $1
fi
else
echo "Too many arguments!"
fi
}
# カレントディレクトリに存在するディレクトリとファイルの検索
function lgrep()
{
if [ "$#" -eq 0 ]; then
echo "Please specify Regular Expression."
elif [ "$#" -eq "1" ]; then
OLDIFS=$IFS
IFS=$'\n\t'
for OBJECT in $(\ls -A --group-directories-first | \grep -iE "$1")
do
ls -AdhlF $OBJECT
done
unset OBJECT
echo ""
IFS=$OLDIFS
else
echo "Too many arguments!"
fi
}
# パターンにマッチするファイル内容を検索する
function datagrep()
{
if [ "$#" -eq 2 ]; then
local IFS_BACKUP=$IFS
IFS=$''
for OBJECT in $(\find . -type f -name "${1}" -print0 | \xargs -0 \grep -inE "${2}")
do
echo "${OBJECT}"
done
echo ""
IFS=$IFS_BACKUP
elif [ "$#" -eq 3 ]; then
# 第1引数で指定したディレクトリが存在するか確認する
if [ ! -d "$1" ]; then
echo "Not Exist Directory $1" 1>&2
return 1
fi
local IFS_BACKUP=$IFS
IFS=$''
# 現在のカレントディレクトリを一時的に保存する
local CURRENTDIR=$(\pwd)
# 第1引数で指定したディレクトリに移動する
cd "${1}";
# 第2引数で指定したパターンを使用して検索する
for OBJECT in $(\find . -type f -name "${2}" -print0 | \xargs -0 \grep -inE "${3}")
do
echo "${OBJECT}"
done
# カレントディレクトリに戻る
cd "${CURRENTDIR}"
echo ""
IFS=$IFS_BACKUP
unset -v OBJECT
else
echo "Specify Arguments." 1>&2
fi
return 0
}
# manコマンドの結果をfirefoxで閲覧
function manh()
{
if [ "$#" -eq 0 ]; then
echo "Too few arguments!"
elif [ "$#" -eq "1" ]; then
man --html=firefox $1 &
else
echo "Too many arguments!"
fi
}
# KVMの起動
function startkvm()
{
local KVM_STATUS=$(sudo systemctl status libvirtd | grep "Active:" | grep -ie "dead")
if [ -n "KVM_STATUS" ]; then
sudo systemctl start libvirtd
fi
local NETWORK_STATUS=$(sudo virsh net-info default | grep -ie "起動中" -ie "Active" | grep -ie "no")
if [ -n "$NETWORK_STATUS" ]; then
sudo virsh net-start default
fi
}
# KVMの停止
function stopkvm()
{
local NETWORK_STATUS=$(sudo virsh net-info default | grep -ie "起動中" -ie "Active" | grep -ie "yes")
if [ -n "$NETWORK_STATUS" ]; then
sudo virsh net-destroy default
fi
local KVM_STATUS=$(sudo systemctl status libvirtd | grep "Active:" | grep -ie "running")
if [ -n "KVM_STATUS" ]; then
sudo systemctl stop libvirtd libvirtd.socket libvirtd-admin.socket libvirtd-ro.socket
fi
}
# Apache2とMySQLの起動
function startlamp()
{
local APACHE2_STATUS=$(sudo systemctl status apache2 | grep -ie "Active:" | grep -ie "dead")
if [ -n "APACHE2_STATUS" ]; then
sudo systemctl start apache2
fi
local MYSQL8_STATUS=$(sudo systemctl status mysql | grep -ie "Active:" | grep -ie "dead")
if [ -n "MYSQL8_STATUS" ]; then
sudo systemctl start mysql
fi
}
# Apache2とMySQLの停止
function stoplamp()
{
local APACHE2_STATUS=$(sudo systemctl status apache2 | grep "Active:" | grep -ie "running")
if [ -n "APACHE2_STATUS" ]; then
sudo systemctl stop apache2
fi
local MYSQL8_STATUS=$(sudo systemctl status mysql | grep "Active:" | grep -ie "running")
if [ -n "MYSQL8_STATUS" ]; then
sudo systemctl stop mysql
fi
}
# 環境変数PATHの設定
function SetPATH()
{
OLDIFS=${IFS}
IFS=$':'
BEFORE_HOME='$HOME'
AFTER_HOME=${HOME}
PATH_NAME=$(echo ${1//${BEFORE_HOME}/${AFTER_HOME}})
SLASH=$(echo ${PATH_NAME: -1:1})
if [ ${SLASH} = "/" ]; then
LENGTH="${#PATH_NAME}"
let LENGTH=${LENGTH}-1
PATH_NAME=$(echo ${PATH_NAME:0:${LENGTH}})
fi
if [ ! -d ${PATH_NAME} ]; then
echo "No Exist Directory"
return 1
fi
EXIST_FLAG=0
for VALUE in ${PATH}
do
if [ ${VALUE} = ${PATH_NAME} ]; then
EXIST_FLAG=1
break
fi
done
if [ ${EXIST_FLAG} -eq 0 ]; then
export PATH="$PATH_NAME:$PATH"
elif [ ${EXIST_FLAG} -eq 1 ]; then
echo "Already Exist ${PATH_NAME} in PATH " 1>&2
fi
unset -v OLDIFS SLASH LENGTH BEFORE_HOME AFTER_HOME PATH_NAME EXIST_FLAG VALUE
IFS=${OLDIFS}
return 0
}
function SetLIBRARY()
{
OLDIFS=${IFS}
IFS=$':'
BEFORE_HOME='$HOME'
AFTER_HOME="$HOME"
PATH_NAME=$(echo ${1//${BEFORE_HOME}/${AFTER_HOME}})
SLASH=$(echo ${PATH_NAME: -1:1})
if [ ${SLASH} = "/" ]; then
LENGTH="${#PATH_NAME}"
let LENGTH=${LENGTH}-1
PATH_NAME=$(echo ${PATH_NAME:0:${LENGTH}})
fi
if [ ! -d ${PATH_NAME} ]; then
echo "No Exist Directory"
return 1
fi
EXIST_FLAG=0
for VALUE in ${PATH}
do
if [ ${VALUE} = ${PATH_NAME} ]; then
EXIST_FLAG=1
break
fi
done
if [ ${EXIST_FLAG} -eq 0 ]; then
export LD_LIBRARY_PATH="$PATH_NAME:$LD_LIBRARY_PATH"
elif [ ${EXIST_FLAG} -eq 1 ]; then
echo "Already Exist ${PATH_NAME} in PATH " 1>&2
fi
unset -v OLDIFS SLASH LENGTH BEFORE_HOME AFTER_HOME PATH_NAME EXIST_FLAG VALUE
IFS=${OLDIFS}
}
# 環境変数PATHの重複を削除する
function DeleteDuplicate()
{
if typeset -A &>/dev/null; then # 連想配列が使用できるか確認する
# 使える場合
typeset -A _paths
typeset _results
while read -r _p
do
if [[ -n ${_p} ]] && (( ${_paths["${_p}"]:-1} )); then
_paths["${_p}"]=0
_results=${_results}:${_p}
fi
done <<<"${PATH//:/$'\n'}"
PATH=${_results/:/}
unset -v _p _paths _results
else
# 使えない場合はawkを使用する
typeset _p=$(awk 'BEGIN{RS=":";ORS=":"} !x[$0]++' <<<"${PATH}:")
PATH=${_p%:*:}
unset -v _p
fi
}