シェルのdateコマンド(Linux、MacOS/FreeBSD)の演算いろいろ
- Fri
- 23:09
- シェルスクリプト
dateコマンドはLinux系とMacOS/FreeBSD系でパラメータが全然違うのでよく使うものをまとめ。追々追記。
Linux
-j : 任意日付の指定ありの場合、-jオプションをつける
-f : 入力日付のフォーマット
最後の"+〜"は、出力フォーマット
Linux
Linux(GNU coreutils)のdateコマンドは入力日付のフォーマットを勝手に解釈してくれて便利。
"+〜"は、出力フォーマット。位置は、前でも後ろでもOK。MacOSだと最後に指定しないとエラーになる。
-v : 日(d)/月(m)など複数指定可能
複数指定した場合は、最初のパラメータから計算されていくので、「-v-1d -v-1m 」と「-v-1m -v-1d」では結果が異なる。
Linux
-d にそのまま続けて加減算の日/月を指定
減算の場合は、「1 day ago」とか「1 month ago」とか。MacOSの場合と違って順番は関係ない様子。
日付の計算(加減算)を行う場合、どちらが便利なのかは微妙な感じがする。MacOS/FreeBSDの方が便利そうだがバグを生む原因にもなりそう。
dateコマンドのバージョン
MacOS$ uname -a Darwin MacbookM1 Darwin Kernel Version 20.3.0: Thu Jan 21 00:06:51 PST 2021; root:xnu-7195.81.3~1/RELEASE_ARM64_T8101 arm64 $ man date | tail -3 A date command appeared in Version 1 AT&T UNIX. BSD May 7, 2015 BSD
Linux
$ uname -a Linux XXX 4.14.94-164.ELK.el6.x86_64 #1 SMP Wed Jan 16 16:56:35 CST 2019 x86_64 x86_64 x86_64 GNU/Linux $ date --version date (GNU coreutils) 8.4 Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later
任意日付の指定方法
MacOS-j : 任意日付の指定ありの場合、-jオプションをつける
-f : 入力日付のフォーマット
最後の"+〜"は、出力フォーマット
$ date -jf "%Y-%m-%d" 2021-03-01 "+%Y%m%d" 20210301フォーマットが一致しないとエラーとなる
$ date -jf "%Y-%m-%d" 2021/03/01 "+%Y%m%d" Failed conversion of ``2021/03/01'' using format ``%Y-%m-%d'' date: illegal time format
Linux
Linux(GNU coreutils)のdateコマンドは入力日付のフォーマットを勝手に解釈してくれて便利。
"+〜"は、出力フォーマット。位置は、前でも後ろでもOK。MacOSだと最後に指定しないとエラーになる。
$ date "+%Y-%m-%d" "-d 20210301" 2021-03-01 $ date "+%Y-%m-%d" "-d 2021-03-01" 2021-03-01 $ date "+%Y-%m-%d" "-d 2021/03/01" 2021-03-01 $ date "-d 20210301" "+%Y-%m-%d" 2021-03-01
日付の演算(加算・減算)、前日・翌日の取得
MacOS-v : 日(d)/月(m)など複数指定可能
複数指定した場合は、最初のパラメータから計算されていくので、「-v-1d -v-1m 」と「-v-1m -v-1d」では結果が異なる。
前日(−1)を取得 $ date -v-1d -jf "%Y-%m-%d" 2021-03-01 "+%Y%m%d" 20210228 1日前のさらに1か月前を取得 $ date -v-1d -v-1m -jf "%Y-%m-%d" 2021-03-01 "+%Y%m%d" 20210128 1か月前の1日前を取得 $ date -v-1m -v-1d -jf "%Y-%m-%d" 2021-03-01 "+%Y%m%d" 20210131
Linux
-d にそのまま続けて加減算の日/月を指定
減算の場合は、「1 day ago」とか「1 month ago」とか。MacOSの場合と違って順番は関係ない様子。
$ date "+%Y-%m-%d" "-d 20210301 1 month ago 1 day ago" 2021-01-31 $ date "+%Y-%m-%d" "-d 20210301 1 day ago 1 month ago" 2021-01-31
日付の計算(加減算)を行う場合、どちらが便利なのかは微妙な感じがする。MacOS/FreeBSDの方が便利そうだがバグを生む原因にもなりそう。
bashでforループ
- Mon
- 16:00
- シェルスクリプト
たまにbashのコマンドラインで複数ファイルを、なんやかんやでワンライナーのforループで処理させたい場合がありますが、たまにやるので ;(セミコロン)の位置を忘れたりするのでメモ。
適当にファイルを作成。
で、ワンライナーのサンプル。
適当にファイルを作成。
$ touch a.txt b.txt c.txt a.log $ ll total 0 drwxr-xr-x 1 user01 user01 4096 Jan 18 15:51 . drwxr-xr-x 1 user01 user01 4096 Jan 18 15:50 .. -rw-r--r-- 1 user01 user01 0 Jan 18 15:51 a.log -rw-r--r-- 1 user01 user01 0 Jan 18 15:51 a.txt -rw-r--r-- 1 user01 user01 0 Jan 18 15:51 b.txt -rw-r--r-- 1 user01 user01 0 Jan 18 15:51 c.txt $
で、ワンライナーのサンプル。
$ for FILE in `ls *.txt`; do echo "FILE=$FILE"; done FILE=a.txt FILE=b.txt FILE=c.txt $
lftpコマンドによるsftpサーバへのアクセス
- Sun
- 23:39
- シェルスクリプト
以前、lftpコマンドによるFTPSサーバへのアクセスでFTPSへのアクセスを行いましたが、今回はsftpサーバへアクセスします。
sftpコマンドでもできるのですが、パスワードの扱いやもろもろでlftpコマンドでやった方が簡単だったりしたのでそのメモ。
FTPSはFTP over SSL/TLSで、中身はFTPのままです(暗号化はしてますが)。一方、SFTPはSSH File Transfer Protocolで、雰囲気的にはFTP over SSHな感じですが実際にはFTPとは全く別物です。しかし、lftpコマンドを使う場合は、そういったことを意識することなく両方のサーバにFTPライクなコマンドでアクセスできるので便利。
lftpによるsftpサーバへのアクセス
ちなみに、前回のftpsの例は
FTPS - Wikipedia ポート番号は990
SSH File Transfer Protocol - Wikipedia ポート番号は22
sftpコマンドでもできるのですが、パスワードの扱いやもろもろでlftpコマンドでやった方が簡単だったりしたのでそのメモ。
FTPSはFTP over SSL/TLSで、中身はFTPのままです(暗号化はしてますが)。一方、SFTPはSSH File Transfer Protocolで、雰囲気的にはFTP over SSHな感じですが実際にはFTPとは全く別物です。しかし、lftpコマンドを使う場合は、そういったことを意識することなく両方のサーバにFTPライクなコマンドでアクセスできるので便利。
lftpによるsftpサーバへのアクセス
lftp -c "open -u ${USER}:${PASSWD} -p ${DEST_PORT} sftp://${DEST_HOST}; $CMD"
ちなみに、前回のftpsの例は
lftp -c "open -u ${USER},${PASSWD} -p ${FTPS_PORT} ${FTPS_HOST}; $CMD"
FTPS - Wikipedia ポート番号は990
SSH File Transfer Protocol - Wikipedia ポート番号は22
makeからシェルコマンドを実行して結果を変数に取得
- Sat
- 00:35
- シェルスクリプト
久々にmakefileをさわる事があり、シェルの実行結果を取得する必要があったのでそのサンプル。
シェルでやってることは、単にファイル名を取得して実際にはそのファイルにたいして何かしらの処理をするってことだけ。ここではファイル名をechoしてるだけ。
makefile
ファイルの一覧:
実行結果:
コマンドの前にある@はmake自体のechoを抑制するもの。付けない場合の実行結果は下記の通り。
シェルでやってることは、単にファイル名を取得して実際にはそのファイルにたいして何かしらの処理をするってことだけ。ここではファイル名をechoしてるだけ。
makefile
01: 02: 03: 04: 05: 06: 07: | all: @echo "*** start" @FILES=`ls *.txt`; \ for FILE in $$FILES; do \ echo " file=$$FILE"; \ done; @echo "*** end" |
ファイルの一覧:
[user01@pc02 shell]$ l 合計 4 drwxrwxr-x. 2 user01 user01 78 2月 18 00:20 . drwxrwxr-x. 3 user01 user01 18 2月 17 23:55 .. -rw-rw-r--. 1 user01 user01 0 2月 17 23:59 aaa.txt -rw-rw-r--. 1 user01 user01 0 2月 17 23:59 bbb.txt -rw-rw-r--. 1 user01 user01 0 2月 17 23:59 ccc.log -rw-rw-r--. 1 user01 user01 128 2月 18 00:20 makefile -rw-rw-r--. 1 user01 user01 0 2月 17 23:59 test.txt
実行結果:
[user01@pc02 shell]$ make *** start file=aaa.txt file=bbb.txt file=test.txt *** end
コマンドの前にある@はmake自体のechoを抑制するもの。付けない場合の実行結果は下記の通り。
[user01@pc02 shell]$ make echo "*** start" *** start FILES=`ls *.txt`; \ for FILE in $FILES; do \ echo " file=$FILE"; \ done; file=aaa.txt file=bbb.txt file=test.txt echo "*** end" *** end
lftpコマンドによるFTPSサーバへのアクセス
- Sun
- 22:45
- シェルスクリプト
lftpコマンドによるFTPSサーバへのアクセス Linuxのlftpコマンドでアクセスするだけ。
引数なしてlftpを実行するとシェルっぽい対話形式での接続が可能になります。
-c の引数で直接lftpコマンドを渡すことができ、
-f でlftpコマンドを列挙したファイルを指定して実行できます。
ファイル指定の場合、-f script-file arg1 arg2...のように引数を続けるとファイル内で@1,@2等で展開して使うことができます。
lftp.sh
やってることはいたって単純で、lftp.sh <送信対象ファイル> として実行すると存在しない場合のみ送信する、ということをやっています。
lftpでコマンドを渡すときは、通常のシェルのようにセミコロン(;)で区切ります。
37行目のdebug 3は、接続時の情報や転送状況などデバッグするのに役立ちます。
ちなみに、ポートの21と990の使い分けは特に決めがあるわけではなく、通常のFTPとFTPSと共存させたい時FTPを21でFTPSを990としているようです。また、FTPSをFTPとしても使いたい時はFTPSを21で立てるようです。
引数なしてlftpを実行するとシェルっぽい対話形式での接続が可能になります。
-c の引数で直接lftpコマンドを渡すことができ、
-f でlftpコマンドを列挙したファイルを指定して実行できます。
ファイル指定の場合、-f script-file arg1 arg2...のように引数を続けるとファイル内で@1,@2等で展開して使うことができます。
lftp.sh
01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: | #!/bin/bash USER=lftp_user PASSWD=lftp_passwd FTPS_HOST=ftps01.com FTPS_PORT=990 SRC_DIR=$HOME DST_DIR=/tmp FILE=$1 function cmd_lftp () { CMD="$1" debuglog "lftp cmd=[$CMD]" lftp -c "open -u ${USER},${PASSWD} -p ${FTPS_PORT} ${FTPS_HOST}; $CMD" } RC=`cmd_lftp "ls ${DST_DIR}/${FILE}"` LFTP_RC=$? if [ $LFTP_RC -ne 0 ]; then echo "lftp cmd error. rc=$LFTP_RC" exit 1 fi if [ "$RC" = "" ]; then CNT=0 else CNT=`echo $RC | wc -l` fi if [ $CNT -gt 0 ]; then echo "${DST_DIR}/${FILE} exist." exit 0 fi # send file RC=`cmd_lftp "debug 3; mput -O ${DST_DIR}/ ${SRC_DIR}/${FILE}"` LFTP_RC=$? if [ $LFTP_RC -ne 0 ]; then echo "lftp cmd error. rc=$LFTP_RC" exit 1 fi |
lftpでコマンドを渡すときは、通常のシェルのようにセミコロン(;)で区切ります。
37行目のdebug 3は、接続時の情報や転送状況などデバッグするのに役立ちます。
ちなみに、ポートの21と990の使い分けは特に決めがあるわけではなく、通常のFTPとFTPSと共存させたい時FTPを21でFTPSを990としているようです。また、FTPSをFTPとしても使いたい時はFTPSを21で立てるようです。