Shell Script
2015/3/6更新
sudoでコマンドを実行した結果を書き込み権限のないファイルにリダイレクトしようとするとパーミッションエラーになる。
% ls -l /tmp/test -rw-r--r-- 1 root root 3 3月 6 22:42 /tmp/test % sudo id > /tmp/test -bash: /tmp/test: 許可がありません
コマンド自体はrootで実行されるものの、リダイレクトは一般ユーザで実行されるのでこのような現象になる。
リダイレクトも含めてrootで実行したい場合はsudoでshを実行し、-cオプションでリダイレクトを含めたコマンド全体を「"」でくくればよい。
% sudo sh -c "id > /tmp/test" % cat /tmp/test uid=0(root) gid=0(root) groups=0(root)
2023/12/27更新
対応バージョン: 8.22
dateコマンド(GNU date)を使って2つの日時の差分時間を計算するスクリプトを作ってみた。
cal_time
#!/bin/bash # 日時の差分計算 # # (使用例) # $ cal_time 20231231 12:00 20240101 00:20 # 12h20m # 引数取込 from_date=$1 from_time=$2 to_date=$3 to_time=$4 # 引数チェック if [ ! -n "${from_date}" ] || [ ! -n "${from_time}" ] || [ ! -n "${to_date}" ] || [ ! -n "${to_time}" ]; then echo "usage: `basename $0` from_date from_time to_date to_time (date=YYYYMMDD,time=HH:MM:SS)" exit fi # 通算秒計算 from_total_datetime=$(date --date "${from_date} ${from_time}" +%s) to_total_datetime=$(date --date "${to_date} ${to_time}" +%s) # 時間/分の差分計算 diff_time=$(expr \( ${to_total_datetime} - ${from_total_datetime} \) / 3600) diff_minute=$(expr \( ${to_total_datetime} - ${from_total_datetime} \) % 3600 / 60) echo ${diff_time}h${diff_minute}m
使い方は以下の通り。
% cal_time 20231231 12:00 20240101 00:20 12h20m
関連資料・記事
2014/8/28更新
対応バージョン: 8.4
dateコマンドを使って日時計算をするには--dateオプションに続けて日時と計算の単位を指定すればよい。
指定できる単位は以下の通り。
年: years
月: months
日: days
時: hours
分: minutes
秒: seconds
これに数字をつけて「2 days ago」のように自然なフレーズで指定すれば日付計算をやってくれる。
以下にいくつかサンプルを示す。dateはGNU版の最近のバージョンであれば特に問題ないだろう。
% date --version date (GNU coreutils) 8.4 :
今日から5日後
% date +%Y%m%d 20140827 % date --date "5 days" +%Y%m%d 20140901
2014/1/1から3日前
日付を指定するとその日を起点に計算される
日時をさかのぼる場合はagoを付ける
% date --date "20140101 3 days ago" +%Y%m%d 20131229
2014/1/1 01:00から3時間前
% date --date "20140101 01:00 3 hours ago" "+%Y%m%d %H:%S" 20131231 22:00
2014/1/1と2013/12/25の差分日数
通算秒に変換した上で計算し、1日の秒数(60秒 x 60分 x 24時間)で割る
通算秒の起点は1970/1/1 00:00 UTC
% expr \( `date --date "20140101" +%s` - `date --date "20131225" +%s` \) / 86400 7
2014/1/1 01:00 と2013/12/25 12:00の差分時間
通算秒に変換した上で計算し、1時間の秒数(60秒 x 60分)で割る
通算秒の起点は1970/1/1 00:00 UTC
% expr \( `date --date "20140101 01:00:00" +%s` - `date --date "20131225 12:00:00" +%s` \) / 3600 157
来週月曜日の日付
相対指定の組み合わせ
% date +%Y%m%d 20140827 % date --date "next monday" +%Y%m%d 20140901
来月の月末日
lastは1{日,時間,秒}戻る指定なので使えない。よって来月の月末日は2ヶ月後の1日から1日戻ることで求める
(誤) ... 来月同日(next month)の一日前(last day)になってしまう
% date +%Y%m%d 20140827 % date --date "next month last day" +%Y%m%d 20140926
(正) ... 2ヶ月後(2 month)の1日から一日前(last day)
% date +%Y%m%d 20140827 % date --date "`date --date "2 month" +%Y%m01` last day" +%Y%m%d 20140930