インストール - Bash

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
2023年4月13日 (木) 20:49時点におけるWiki (トーク | 投稿記録)による版 (→‎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をインストールする。

# CentOS
sudo yum install bash

# SUSE
sudo zypper install bash

# Raspberry Pi
sudo apt install bash


ソースコードからインストール

Bashのビルドに必要な依存関係のライブラリをインストールする。

# CentOS
sudo yum 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'

# 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"

# VS Codeをインストールしている場合
alias scode='code --user-data-dir='<VSCodeのプロジェクトディレクトリ>

alias suse='cat /etc/SUSE-brand'
alias sshpi='ssh <ユーザ名>@<ホスト名またはIPアドレス> -p <ポート番号> -i <暗号鍵のフルパス名>'  # Raspberry Pi向けSSH接続の設定
alias sshxrea='sshpass -p <パスワード> ssh <ユーザ名>@<ホスト名> -p <ポート番号>'  # XREA向け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
}