プロジェクト

全般

プロフィール

シェル芸ブブ化 » 履歴 » バージョン 1

kanata, 2025/04/13 16:39

1 1 kanata
# シェル芸ブブ化
2
3
シェルスクリプトをシェル芸化(ワンライナー)するスクリプト
4
5
{{toc}}
6
7
# Installation
8
9
以下のシェルスクリプトをコピペして使ってください。とりあえず動きはする。
10
なんか別言語で書きなおした方がいいような気がしている。
11
12
ShellGeiBubka.sh
13
14
~~~
15
#!/bin/bash
16
17
# シェル芸ブブ化 ver 0.62
18
# kanata from https:/raintrees.net
19
20
#--------------#
21
# 引数チェック #
22
#--------------#
23
if [ -r "${1}" ]
24
then
25
  :
26
else
27
  echo "file can not open. [$1]"
28
  exit 1
29
fi
30
31
#------------------------------------------------------------#
32
# 処理中に出現する引数の対応(置換)                           #
33
# →しんどいので、とりあえずやめる                           #
34
# 例えば、echo $1 |awk '{print $1}' のパターンが解決できない #
35
#------------------------------------------------------------#
36
if cat "${1}"|grep -e '\$[1-9]' -e '\${[1-9]' >/dev/null
37
then
38
  echo "#------------------------------------------------------------------------------#"
39
  echo "#                             シェル芸ブブ化(注意)                             #"
40
  echo "#------------------------------------------------------------------------------#"
41
  echo '# シェルスクリプトの中に、引数($1 .. $9)の処理をしている箇所があります。'
42
  echo "# シェル芸は引数が使えませんので、変換後の結果に対して手動にて修正してください。"
43
  echo "# 中断する場合は、[Ctrl + c]にて中止してください。"
44
  echo "#-------------------------------------------------------------------------------"
45
  cat "${1}"|nl|grep -e '\$[1-9]' -e '\${[1-9]' |grep -v '^\s*[0-9]*\s*#'|sed 's/^/# /g'
46
  echo "#-------------------------------------------------------------------------------"
47
  echo "# Prease puress [Enter]"
48
  read DUMMY
49
fi
50
#ARG1=`echo "$2"|sed 's@/@\\\\/@g'`
51
#ARG2=`echo "$3"|sed 's@/@\\\\/@g'`
52
#ARG3=`echo "$4"|sed 's@/@\\\\/@g'`
53
#ARG4=`echo "$5"|sed 's@/@\\\\/@g'`
54
#ARG5=`echo "$6"|sed 's@/@\\\\/@g'`
55
#ARG6=`echo "$7"|sed 's@/@\\\\/@g'`
56
#ARG7=`echo "$8"|sed 's@/@\\\\/@g'`
57
#ARG8=`echo "$9"|sed 's@/@\\\\/@g'`
58
#ARG9=""
59
#ARG_SH="1"
60
61
#------------------------------#
62
# 処理中に出現し得るexitの代替 #
63
#------------------------------#
64
EXIT='echo "This ShellGei run exit. Press [Ctrl + c]";read DUMMY'
65
66
#--------#
67
# 主処理 #
68
#--------#
69
70
SHELLSCRIPT="$1"
71
while read LINE
72
do
73
  # 空行を削除
74
  if echo ${LINE}|grep -e '^\s*#' -e '^\s*$' >/dev/null
75
  then
76
    continue
77
  fi
78
  
79
  # シェバンとコメント行を無視
80
  if echo ${LINE} |grep -e '^\s*#' >/dev/null
81
  then
82
    continue
83
  fi
84
85
  # exitを置換
86
  if echo ${LINE} |grep -e '^\s*exit' >/dev/null
87
  then
88
    LINE=`echo ${LINE}|sed "s/exit \+[0-9]\+/${EXIT}/g"`
89
  fi
90
91
  # 特殊なシェル変数を置換
92
  #  LINE=`echo ${LINE}|sed 's/\${@}/\$@/g' |sed 's/\$@/____ARG____/g'|sed 's/____ARG____/\$1 \$2 \$3 \$4 \$5 \$6 \$7 \$8 \$9/g'`
93
  #  LINE=`echo ${LINE}|sed 's/\${#}/\$#/g' |sed 's/\$#/____ARG____/g'|sed "s/____ARG____/${ARG_SH}/g"`
94
95
  # 引数を置換
96
  #if echo ${LINE}|grep -e '\$[1-9]' -e '\${[1-9]' >/dev/null
97
  #then
98
  #  LINE=`echo ${LINE}|sed 's/\${1}/\$1/g' |sed 's/\$1/____ARG____/g'|sed "s/____ARG____/${ARG1}/g"`
99
  #  LINE=`echo ${LINE}|sed 's/\${2}/\$2/g' |sed 's/\$2/____ARG____/g'|sed "s/____ARG____/${ARG2}/g"`
100
  #  LINE=`echo ${LINE}|sed 's/\${3}/\$3/g' |sed 's/\$3/____ARG____/g'|sed "s/____ARG____/${ARG3}/g"`
101
  #  LINE=`echo ${LINE}|sed 's/\${4}/\$4/g' |sed 's/\$4/____ARG____/g'|sed "s/____ARG____/${ARG4}/g"`
102
  #  LINE=`echo ${LINE}|sed 's/\${5}/\$5/g' |sed 's/\$5/____ARG____/g'|sed "s/____ARG____/${ARG5}/g"`
103
  #  LINE=`echo ${LINE}|sed 's/\${6}/\$6/g' |sed 's/\$6/____ARG____/g'|sed "s/____ARG____/${ARG6}/g"`
104
  #  LINE=`echo ${LINE}|sed 's/\${7}/\$7/g' |sed 's/\$7/____ARG____/g'|sed "s/____ARG____/${ARG7}/g"`
105
  #  LINE=`echo ${LINE}|sed 's/\${8}/\$8/g' |sed 's/\$8/____ARG____/g'|sed "s/____ARG____/${ARG8}/g"`
106
  #  LINE=`echo ${LINE}|sed 's/\${9}/\$9/g' |sed 's/\$9/____ARG____/g'|sed "s/____ARG____/${ARG9}/g"`
107
  #fi
108
109
  # then,else,doの末尾には;を付けない
110
  if echo ${LINE} |grep -e '\s*then\s*$' -e '\s*else\s*$' -e '\s*do\s*$' >/dev/null
111
  then
112
    printf "%s " "${LINE}"
113
  else
114
    printf "%s ; " "${LINE}"
115
  fi
116
done < $SHELLSCRIPT
117
118
echo
119
exit 0
120
~~~
121
122
# Usage
123
124
~~~
125
$ ShellGeiBubka.sh [変換したいシェルスクリプト] 
126
~~~
127
128
実行例
129
130
~~~
131
$ ShellGeiBubka.sh example.sh
132
~~~
133
134
# Specification
135
136
以下は、単純に未対応
137
138
* 関数の変換に未対応
139
* case文の変換に未対応
140
141
そして、シェル芸はシェルスクリプトと比べて意外に制限があることが解る。
142
143
* IFS変数に改行のみを設定しているスクリプトはうまく変換できない(どうしようもない)。
144
* 引数($1 .. $9)は、変換後に手修正が必要
145
146
> 本当は、自動で埋め込もうと思ったんだけど、これがまぁ、めんどくさいことになってて、、
147
> echo $1 |awk '{print $1}' とかあると動かない($1を誤変換する。awkの$1は変換したくない)。
148
> 特殊なシェル変数($$ $# $@ など)も取り扱いをどうするか悩む。
149
150
ここらへん、シェル芸勉強会で発表したいぐらい。
151
152
# Background
153
154
## 何故作ったか
155
156
上田先生主催の[シェル芸勉強会](https://blog.ueda.asia/?tag=%E3%82%B7%E3%82%A7%E3%83%AB%E8%8A%B8%E5%8B%89%E5%BC%B7%E4%BC%9A)をちょくちょく拝見するも、「1行で出来ないわコレ・・・」という挫折感を味わう。
157
158
そうや・・・シェルスクリプト作ってから1行にすればいいんや・・・と思いたつ←いまココ
159
160
しかし、まぁ、なんだな。シェル芸の美学に反するような気がしないでもない。
161
162
## 名前の由来
163
164
ある日突然、降りてきた。
165
しかしググると、もう既に発言している人がいた。僕だけじゃなかった。
166
167
参考:[セルゲイ・ブブカ](https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%AB%E3%82%B2%E3%82%A4%E3%83%BB%E3%83%96%E3%83%96%E3%82%AB)