Bashでプログラミング [転載禁止]©2ch.net
Bash - GNU Project - Free Software Foundation
https://www.gnu.org/software/bash/ bashはUnixシェルです。
bashを使ったシェルスクリプティングテクニックや
プログラミングについて和気あいあいとそしてほのぼのと語り合いたいと
思ってこのスレを建てました。よろしくお願いいたします。 シェルスクリプトクソめんどくせぇ。
どこでも動くように作る必要があるものだから
仕方なく作ってるけど、パスにスペースが入ったらとか、
くそめんどくせぇ もうスクリプトはpythonでよくね?
Bashが動くような環境ならpythonがほぼ間違いなく動くから、制限だらけのBashで書く理由が思いつかない。 >>3
ピラフも昔はシェル間の互換性とかに気を配ってたよね。
でもある日悟ったんだよね、超めんどくせえと。
それ以来bashで動けばなんでも良いって思うようになった。
パスにスペースが入ることにも目をつぶるようになった。めでたしめでたし。 >>4
pythonいいよねpython。
一貫性があってシンプルでわかりやすい。
黒魔術perlとは違うよね。
コマンドを実行するだけとか、他のプログラムをキックするだけとか
そういうのだったらシェルスクリプトでいいんだけど、構造化が
必要なほどのプログラムになるときつい。 ノウハウが好きな人にはbashはたまらないと思うんだよね
垂涎ものだよ、たとえバッドでも。バッドでも! パスにスペースが入ってるとパスが引数として解釈されたり、
最悪の場合、脆弱性につながりそうで怖いんだが。 >>7
> たとえバッドでも。バッドでも!
[ コマンドの存在が、一番のバッドだけどなw >>8
わかる。-とかもだよね。これオプションじゃないのよー!みたいな。
シェルを広く公開するならそういうのにも対応しといたがいいのだろうけど、
内輪で使うならまあないっしょ大丈夫っしょ問題ないっしょ!と念じて目をつぶって地蔵の
ふりをするのもありだと思うよ。 >>9
マジで!?ピラフそのコマンド使ったことない。ちょっと調べてみる。 [はtestコマンドだったのか。てっきりbashのsyntaxだとばかり思ってた。 [ "$var" = "test" ]
意味
コマンド名 ・・・ [
第一引数 ・・・ "$var"
第二引数 ・・・ =
第三引数 ・・・ "test"
第四引数 ・・・ ]
考えてみよう!
[ "$var" = "test"] なぜ "test" と ] の間のスペースをなくすとエラーになるのか?
[ $var = "test" ] なぜ 変数名を "" で括るのが一般的なのか? なぜ他の言語のように
if [$var="test] then
fi
とシンプルにかけないのか?
[ コマンドを考えついた奴は、俺頭いい!って思っちゃったんだろうな。
そのせいでシェルスクリプトの構文を改善する機会がなくなった。
シェルスクリプトは変数への代入はできるが変数の参照はできない。
できるのは変数の中身の文字列展開だけ。
それがパスにスペースが有る場合の問題にまで影響してるのさ。
くっそ言語、くっそ言語、 >>18
このスレに書き込まずにはいられなかったんなら
お前も参加しろよw >>18
みんなでここをいいドヤ顔スレにしよう(提案(前向き(全力(社畜 どうしてピラフはわざわざ、プログラム板から、
Linux板にまで出てきたのですか?
皆で、オブジェクト指向のPowerShellへ、移行しませう。
他には、VBScript, JScript もあるし
.NETの世界は、極楽ですぜw >>22
糞じゃない、ピラフだ。
UnixってFreeBSDとかそういうのじゃないの?
ピラフLinux使ってるの。だからスレ建てたの。許して。 >>21
VBScriptはピラフが一番好きなプログラム言語だよ。
いいよねーあれ。Linuxでも使えたら良いのにって毎日思ってるよ。
Linux環境で動く.NET Coreが発表されて.NETはますます勢いを増しそうだよね。
PowerShellと.NET Coreはピラフも興味を持っています。今後ともよろしくお願いいたします。 ピラフさあ、困ってることがあって
標準出力と標準エラー出力を同じファイルに書き出して、
かつ、標準エラー出力のみを画面に出力したいんだよね。
そのやり方がどうしてもわからなくて教えて欲しいんです。
教えてください、おねがいします。 SNSじゃねぇんだから、>>22のスレに移動しろよ。 >>26
>>22はUnix板だよ。
アメリカの議会で税金を話し合ってるときに
中国の税金はどうとか言うのは場違いだよね。
ピラフはUnix使ってないし。ここがSNSじゃないとも思ってないし。
>>22には移動しないし。 >>28
お前が誰だ。なんだペンギンて。なめてんのか。 vipq2が高ければこのスレ落とすんだけどなぁ
無念 >>30
どうしてそんな酷いことするの?
ピラフのこと嫌いなの? >>25
tee を使えば、画面とファイルに、同時に出力できる teeコマンドとはpeeという単語をもじって作られた単語
peeとはおしっこ(をする)という意味で
(ファイルに書きだしたものが画面に)漏れる
という所から来ている。 >>3
"C:\Program Files" とかくくるだけやん
>>17
変数の参照ってどういう意味だ?
>>24
VBSやPowerShellは1GBくらいの巨大なテキストのログを
調べようとしたら、1GBのオブジェクト作ってメモリ関係のエラーが出て
ワロタよ
Unixの小さいメモリで動くコマンドをパイプでつなげる方がいいわ
DOS・NTコマンドもUnix思想だから、PowerShellやVBSをあきらめて
NTコマンドをパイプでつないでなんとか解決したけどさ。
いちいちオブジェクト作るとか大げさだわ >>33
やろうとしたいことちゃんと読んだ?
( echo 1; echo 2>&2; echo 3>1; echo 4>&2)
みたいなコマンドから
1
2
3
4
の出力と
1
3
の出力を分離したいって意味だと思ったんだが >>36
cronで頑張るわけでも無いだろうし、管理出来ていないものを無理くりやって保守できなくなる未来しか見えない。筋が悪いのでアホでも管理できるよう、KISSがいいね。 >>39
____
/ \
/ ─ ─\
/ ⌒ ⌒ \ ハハッ超ワロス 笑い死ぬわ
| ,ノ(、_, )ヽ |
\ トェェェイ /
/ _ ヽニソ, く >>33
teeって標準出力を受け取るじゃん。
標準エラー出力のみを画面に出力するとともに
標準出力と標準エラー出力を同じファイルに出力したい。
とても難しい。とてもわからない。とても教えてほしい。
>>36
そうなんよ。わからないんよ。教えてほしいんよ。お願いするんよ。 >>35
んなアホな。VBScriptはできる子だよ。ピラフが証明してみせるよ。 % cat test.sh
( echo 1; echo 2 >&2; echo 3; echo 4 >&2 )
% : > log; stdbuf -oL -eL bash test.sh 2>>log | tee -a log
1
3
% cat log
2
1
3
4
stdout と stderr との同期とれてないのが、、うーん 標準出力はバッファリングされて、
ある程度データがたまってから出力されるが、
標準エラーは重要度が高いため、
バッファリングされずに、即画面に出力される
>>3
ファイル名には、半角英数字と「_」アンダーバーだけを、
使った方がよい。外人の作るアプリでは、
日本語などは考慮されていないことが多いから
Mac用に、PowerShellでファイル名の、
半角スペースをアンダーバーに変換する、
プログラムを書いたりした >>46
> 外人の作るアプリでは、
> 日本語などは考慮されていないことが多いから
えっとな、俺日本人。
今は俺(=日本人)が作るアプリの話してる。 それからスペースは日本語じゃない。
半角英数字と「_」アンダーバーだけを使った方がよい理由が、
日本語を考慮してないからというのは、理屈がおかしい >>43
簡単なものは簡単なままにしておけクソ野郎 UNIX シェルスクリプト・コマンドブック 第3版
山下哲典、2015
Software Design 2014/1
にも、シェルの特集が40ページ分、載っている
まあ、1〜2週間あれば、そこそこ出来る
ただ、exportを付けないシェル変数は、
同一プロセス内でのみ有効で、
下記のサブシェルのような、別のプロセスには引き継がれない
` ` または、$( ) によるコマンド置換
( ) によるグルーピング
パイプ・リダイレクト
シェル変数を、別のスクリプトでも使いたいのなら、
. または、source コマンドで、
スクリプトをカレントシェル上に呼び出すと、
同一プロセス内での実行となる
sh スクリプト名 → 別のプロセス(子プロセス)
. スクリプト名 → 同一プロセス シュエルスクリプトの関数にするか、
それとも外部プログラムにするか、
どっちがいい? >>52
動くならどっちでもいい。直感的にわかりやすい。コードの見通しが良くなる方が望ましい。 GTK+のプログラミングマスターした人いる?
紙資料で3.5cmの厚みなんだ。
為になるよ。 >>27
bashはOSに依存しないし、該当スレはbashなりzshなり使用するシェルをきちんと申告すれば対応してくれる
それ以上に理由がない限りスレを立てる意味がない >>55
UNIX板はUNIXに依存してるでしょうが。
女性専用の老人ホームに若くてピチピチの可愛いギャルが
入居するようなものだよ。女に変わりはないだろうけども
不適切だよね。老人じゃないし、可愛いし、ピチピチだし。
場を弁えるってそういうことだと思う。若い人が新たにコミュニティを作る
ことには意味があると思うし、ピラフは梯子(テコ)でも動かない! というスピリッツで単発スレ立てする人は自分が満足すると埋め立ての責任を持たず放置する傾向にあるんだよな。
ちゃんと1000まで話題を提供してくれるの?(´・ω・`) >>59
みんなでここを良いスレにしようよ。
ピラフだけでは無理。みんなで力を合わせようよ。 >>60
あのさ、>>45 に対して礼のひとつも言わないのは人としてまずくない? >>62
表示したいのはエラー出力やし人格否定するほどではないな
$ cat test.sh
#!/bin/sh
echo 1; echo 2 >&2; echo 3; echo 4 >&2
$ ( ./test.sh >> log ) 2>&1 | tee -a log
2
4
$ cat log
1
2
3
4
保証はせーへんけどな >>62
> あのさ、>>45 に対して礼のひとつも言わないのは人としてまずくない?
ですよね。お礼は三行。常識です。 ☆ 日本の核武装は早急に必須ですわ。☆
総務省の『憲法改正国民投票法』、でググってみてください。
日本国民の皆様方、2016年7月の『第24回 参議院選挙』で、日本人の悲願である
改憲の成就が決まります。皆様方、必ず投票に自ら足を運んでください。お願い致します。 bashで30ファイル、計1500行ぐらいの
大作ツール作ったぜw >>65
ピラフもうネタ切れだからさ、なんか話題あったら書き込んで。
遠慮しなくていいから。みんなでここをいいスレにしようよ! 変数の宣言について
たとえば、こういうプログラムを書いたとき
pilafは9回表示されるかと思いきや3回しか表示されない。
fun_testでfun_mainのiを読み書きしてしまうから。
だから、変数はローカル変数で宣言する必要がある。
#!/bin/bash
fun_test() {
i=1
while (( i <= 3 )); do
echo pilaf
(( i++ ))
done
}
fun_main() {
i=1
while (( i <= 3 )); do
fun_test
(( i++ ))
done
}
fun_main 以下のコードは何も表示されない。
#!/bin/bash
echo "hello" | while read msg; do
var=$msg
done
echo $var パイプを使っているから、
その部分がサブシェル(子プロセス)になっていて、
そこで宣言した変数varが、
カレントシェル(親プロセス)に持ち出せない
どういう解決策があったっけ?
export を付ければよいのか?
>>51
に書いておいた echo -ne "hello\nworld" | while read msg; do echo $msg ;done
うっかりしてると最後の行を処理し損ねる こう書き換えるだけでいいよ
while read msg; do
var=$msg
done < <(echo "hello") さて、ではこれはどう表示されるでしょうか?
#!/bin/bash
i=0
while read msg; do
echo "A $msg"
((i+=3))
done < <(while read msg; do
echo "B $msg"
((i+=2))
done < <(echo "hello"))
echo $i 変数の宣言と同時に値を代入を行うと
コマンド置換を使うときにリターンコードを取得できない
fun_getValue() {
return 1
}
fun_main() {
declare value=$(fun_getValue)
echo $?
}
fun_main
上のプログラムは0を出力する
declare value
value=$(fun_getValue)
必然的にこういう形を取ることになる
VBScriptみたい 間接参照はこうすればいいみたいだけどさ、
var=123
ref="var"
echo "${!ref}" # 123
間接代入はどうすればいいの?
一応evalつかってできたけど、これしかない?
eval "$ref"=456 だまってPHPとかC言語とか使えや。
反論不要。だまって使え。
所詮bashはシェルだよ。
プログラミング言語として使おうとしなくていい。 [[ $a = $b ]]
$a はただの文字列として扱われるが、$b はパターンマッチング処理されることに注意
単なる文字列比較をしたい場合は
[[ $a = "$b" ]] または [[ "$a" = "$b" ]]
なお、[ ] と違って [[ ]] は $a を "" で囲む必要はない。 >>83
echoもそうだよね。
いい感じのエラーログを出力しようとしたらファイル丸出し。
a="*** ERROR ***"
echo $a echo には -e という文字列を出力できないという問題があるので
完ぺきを求めるなら、printf "%s\n" "$text" とした方がいい。
なお、echo も printf も それぞれ /bin/echo、/usr/bin/printf という
バイナリがあるが、bash も sh も zsh もシェルビルトイン関数である。 >>85
マジか!?マジでか!!
echo難儀なコマンドだね あー、うん、せやね。
-eだけじゃなくて-nもだめだし-eneもだめ
さて$aに任意の文字が入っている時、それをechoで問題なく出力するにはどうするか?
もちろん、$aに \e[33m のような文字列が入っていることがあるが、
printf "%s\n" $a と同じようにそのまま出力するというのが条件。
とまで書かないといかんよね。 bashでは知らないけどzshでは
echo e- |rev
とすると表示できたよ。 a="-e"
echo "$a" |rev
zshでも表示されねーじゃねーかwww いや、その条件ならa='e-'にしてrevするべきだろ。 条件は $a に -e が入っている場合なんですが?
もちろん $a には-e だけじゃなくて、-n や -ene や
e-が入っていることもあります。 >>91
a="ab"
$ echo -n $a | wc -c
2
$ echo -n $'\0'$a | wc -c
3
1文字増えちゃってますよ? そんな偉そうに言われてもな。89にたいする90の解答って.. Bashでツールを作ったんですけど、ここで紹介するのありですか?
ソースコードはかなりまじめに書いています。
ドキュメントと仕上げでもう少しだけ時間が掛かりそうですけど。 >>98
┓┏
(^ω^) アリだっ!
┌.ゝ .ノ┐
┌'、_丿┐
┛ ┗ >>72
> while (( i <= 3 )); do
> echo pilaf
> (( i++ ))
> done
((i++)) 【let i=++】と
((i+=1)) 【let i=i+1】と
i=$((i+1)) は
厳密には違う。
i=0; ((i++)); echo $? => 1
i=0; ((i+=1)); echo $? => 0
i=0; i=$((i+1)); echo $? => 0
i=-1; ((i++)); echo $? => 0
i=-1; ((i+=1)); echo $? => 1
i=-1; i=$((i+1)); echo $? => 0
set -e をしていると、その場で終了してしまうことになる。
計算のみの用途として、安心して使えるのは i=$((i+1)) だ よく見たらこの例はiが1から始まってるから大丈夫か。 >>102
((φ(・Д´・ *)ホォホォ 勉強になります!! ○
/⌒\ (__)
\●/(__)/⌒\
∩ (・∀・ )\●/ あけおめ
Y  ̄ ||y||  ̄`''φ
Lノ /ニ|| ! ソ >
乂/ノ ハ ヽー´
`ー-、__| 曜日の定数を自動生成しちゃう
for i in $(seq 0 6); do
date -d "$i days" "+%A %w"
done | sort -k 2 | sed -e "s/ /=/" | sed -e "s/^/readonly /" >>106
結果がこれ
readonly Sunday=0
readonly Monday=1
readonly Tuesday=2
readonly Wednesday=3
readonly Thursday=4
readonly Friday=5
readonly Saturday=6 >>107
可読性はタイプ数よりも大切だってことが
よく分かるねw bash使うなら曜日名は配列に格納しておいて入ってくる引数を添字として使えばいいんでないの? PATH の中に空の : があると、カレントディレクトリがコマンドサーチパスに含まれてしまいますが、
環境変数が空であった等の理由により、空の : (ex /usr/local/sbin::/usr/local/bin など)が
パスに含まれてしまうことはよくあります。
カレントディレクトリがコマンドサーチパスに含まれるのはセキュリティーホールになりかねないので、
PATHに空の : が含まれないようにしたいのですが、よい方法はないでしょうか? 変数が空なら何も入れないようにすればいいじゃないですか? そもそもPATHに使われる環境変数が空であることはありえないはずなんだがね。
普通PATHに使われる変数には、定数として決め打ちのパスが代入されているはず。
なぜならば、空が入る可能性があるということは、
空以外の任意の文字列が入るということだろう?
であれば、環境変数に "./" が入ることがあるかもしれないし
"/malware/" という値が入るかもしれない。
カレントディレクトリだけを不正だって意味は無い。 >空であることはありえないはずなんだがね。
そうなんですか、現在の環境じゃインストール後、マニュアル操作で PATH をいじっていないので、
そういうもんだと思っていたのですが、何か問題があるようですね。
どこでそうなってるいるか調べてみます。 わかりました。
<アプリ名>_HOME=<アプリのインストールパス> # この <アプリ名>_HOME は関連ツールから参照される
PATH=$PATH:<アプリ名>_HOME/bin
みたいな記述で、最初の 「<アプリ名>_HOME」 のスペルが間違っていました。
このアプリをすぐ使っていれば気づいたはずですが、インストールした後ほかが忙しくて
ほったらかしにしていたので気づかなかったというオチです。
どうもお騒がせしました。 配列の代入(複製)というのはどうやればできるのでしょうか。 x='123'
y=`date +%m | sed 's/^0//' `
z= expr $y "*" 1000 + $x
cat k-m | sed 's/PPP/$z/'
で ファイル k-mのPPP値を3123に変えたいのですが
$zではだめです。
どうしたらいいでしょう。 >>117
読むのだるいからさ?
問題ない所までは省いて
問題があるところだけ書けよ すまん
echo 'port=PPP' > test
cat test
x=2
sed 's/PPP/'"$x"'/' test
は問題ない。
長いファイルではダメなのかな? cat test の意味は?
必要最小限にしないからわからんのよ。
testの中身の文字もさ、限界ギリギリまで減らしてみて 修正
限界ギリギリまで減らした状態での
動く場合 と 動かない場合 の
2つのパターンを書いてみて k1の内容が
media_dir=/home/foge/Downloads/
network_interface=eth0
port=PPP
serial=6810
で 、シェルクリプトが
z=55555
sed 's/PPP/' あれ 尻切れとんぼ
z=5555
sed 's/PPP/'"$z"'/' k1 の時はOK。
x='123'
y=`date +%m | sed 's/^0//' `
z= expr $y "*" 1000 + $x
echo $z
sed 's/PPP/'"$z"'/' k1 はだめ だからね。
動くやつはそれでいいよ。
動かない方、どこまで想定通りに動いているのか?
想定通りに動いているところは省略して、
想定通りに動いていない所だけ書いてって話をしてるんだよ。 了解
echo $z
で確かに$zには想定とおりの値がでてくる。
しかし sed 's/PPP/'"$z"'/' k1 はだめ。
'"$z"' がいけないと思う。 だが 分からない。 きたならしく 一応できた。 ./s4 `./s5` で。
k1 は既出。 minisldaのポートを安全改善のため毎月変えようと思って
cat s4
awk '{sub("PPP", "'$1'" ); print $0;}' k1
cat s5
x='10000'
y=`date +%m | sed 's/^0//' `
z= expr $y "*" 10 + $x
echo $z それは echo ではなく expr が出力している。
z=`expr $y "*" 1000 + $x`
sed "s/PPP/$z/" k1
でいいんじゃないの? これでちゃんと動いたよ。 shellが違うんでしょうね、うちでは 下ではエラー expr: syntax error
z=`expr $y "*" 1000 + $x`
echo $z
使ってるのは OS :armbian で シェルは わからない 多分、勘違いしているのはここ。
z= expr $y "*" 10 + $x
これは一時的に環境を変更した上でコマンドを起動するための構文。
bash の man の 2520 行目辺りに書かれている。
この場合は環境変数 z に空文字列をセットして expr を起動する。
そして、それが終わったらもう z は存在しない。
だから echo では何も出力されない。 環境変数 $BASH_COMMAND で最後に実行したコマンドが取得できますが
ほんとに最後に実行したコマンドなので
ls | cat
みたいにしたときに当然ながら cat しか取れません
最後に実行したときのコマンドラインに打った文字列
を取得するにはどうしたらよいでしょうか >>131
ありがとう
historyあたりで頑張ります http://unix.oskp.net/sua
XPとかなbashとかコンパイルしたら
動いたけど、バイナリ互換はすごいな curlでAPI叩いてるんだけど返事帰ってくるまでCreating..........みたいに....を増やしたい
どういうふうに書けばいい? >>135
別プロセスで実行して、そのプロセスが生きている間
. を増やし続ければいい 1秒ごとにチェックして生きてたら....を出力死んでたらそのままみたいなことか
やってみるわ windowsでbaプロできるようになるみたいですね(´・ω・`) HOGEDIR="${HOME}/path/to/directory" のように既存のディレクトリへのpathを変数に入れたら下記のような感じで実在チェックした方がいいんでしょうか?
自分は転ばぬ先の杖だと思って(事実、何度かtypoしてます)書くようにしていますが……
if test ! -d "$HOGEDIR"; then
echo '$HOGEDIR is *NOT* a Directory!' 1>&2
exit 1
fi 変数に入れるかどうかは実在チェックの必要性に変化を与えるものではない だがその実在性が極めて疑わしい性的な穴隙に変化を与えられた私はそれに入れる事を夢想し夢精するものである exec 3>$1
みたいにファイルディスクリプタを指定するとき
すでに使われるディスクリプタ番号を避けたいんだけど
どうしたらいいの? Bash詳説みたいな本ないかな?
やっぱオライリーか… open とか、複製する dup でも、未使用のファイルディスクリプタを使う SoftwareDesign 6月号、1,220円 + 税
特集、Bash 再入門・MySQL 最近の言語に慣れると
コマンドラインベースの言語って理解しにくいね
コマンドを文字型変数として理解しようとしてハマる debianとかubuntuにはwhiptailなんてのがデフォルトであるらしい
今まで選択候補をcat -b >&2してからread REPLY </dev/ttyしていたのをさっそく書き換えてみた
けっこうすっきり書けて個人的には大満足 コンソールにできたバイナリを16進で出力するにはどうしたら良いですかね >>150
hexdumpやodで出力すればいいんじゃないですかね 関数を定義したshファイルを実行したあと、その関数を使いたいんだけど
どうしたらいいの? >>154
汎用的に使う関数なら ~/.bashrc に書いて
あとは普通に関数名で実行すればいいだけ
function foo {
}
ならfooで呼び出し。 誰でも簡単にパソコン1台で稼げる方法など
参考までに、
⇒ 『宮本のゴウリエセレレ』 というブログで見ることができるらしいです。
グーグル検索⇒『宮本のゴウリエセレレ』
2UMY6SSHSE ☆ 私たち日本の、改憲を行いましょう。現在、衆議員と参議院の
両院で、改憲議員が3分の2を超えております。
『憲法改正国民投票法』、でググってみてください。国会の発議は
すでに可能です。平和は勝ち取るものです。お願い致します。☆☆ 僕の知り合いの知り合いができた副業情報ドットコム
関心がある人だけ見てください。
グーグルで検索するといいかも『ネットで稼ぐ方法 モニアレフヌノ』
FOJ8E html form で書き込み送信URLエンコードされた文字列をURLデコードした後
変数Aに格納したあと 改行コードを html改行コードに変換したいのですが 改行コードがバイナリコードで格納されているため
変換がうまくできません bash でうまく変換するコードってなにかないですか? html form で書き込み送信URLエンコードされた文字列をURLデコードした後
変数Aに格納したあと 改行コードを < b r >に変換したいのですが 改行コードがバイナリコードで格納されているため
変換がうまくできません bash でうまく変換するコードってなにかないですか? 解決しました
なぜか sed のパイプで変換できなかった
trのパイプで変換してなんとかなりました
なぜだろう? >163
sedで改行をどうこうするのは意外とハイレベルな知識が要るからかな
単に改行を置換したいだけならtr使うほうが筋がいいと思う >>164
urlエンコードから飛んできた文字列をURLデコードした後の文字列はecho
なんかで出力しても隠れてみえない \n が見えない
アスキーコードで書かれた文字列はsedじゃ無理?のようなきがする POSIXのコマンドも今の人達が再設計すれば
もっと良いものが作れるんだろうな 素直にUnix2dos、dos2unix使おう、な? eval使って文字列内で実行するコマンドの返却値も標準出力も取りたいんですがどうしたらいいですか?
evalに渡すのはcurlでhttp取得なんですがurlが変わるのでそこを変数から実行したいんですが$?はevalの結果でcurlのものが取れないんです mysqlで特定の接頭辞がつくテーブルを検索し一括で削除したいのですが、クォーテション処理でうまく動作してくれません
grepで特定の接頭辞を検索してxargsで引数を渡してるのですが、xargs以降のエスケープしたりシングル・ダブルクォートと入れ替えたり
してるのですがうまくいきません。(-pで実行コマンドも確認しました。)
どなたかうまい書き方が分かる方いませんか?
mysql -u ユーザー名 -p -e 'SHOW TABLES FROM テーブル名' |grep 接頭辞_* |xargs -pI '{}' mysql -u ユーザー名 -p -e 'DROP TABLE テーブル名.\'{}\'' 実際に使って知ってる人が助けてくれるんじゃないかと思って見てたけど来ないね。
まあ、「うまくいきません」だけじゃ無理か。
同様なことを SQLite でやるとしたらこんな感じかな。
dbname='test.db'
prefix='a'
echo .table | sqlite3 "$dbname" | tr -s ' ' '\012' |
sed -e "/^$prefix/!d" -e 's/^/drop table / ; s/$/;/ ;' |
sqlite3 "$dbname"
一般的な話として、引数で渡すためにはシェルの文法に従う必要があるから
それを大変だと思うならパイプを使えばいいと思うよ。
そういう使い方ができる場合はね。
3 日近く経ってるし、もう自分で解決してるよね。 そもそも何が問題なのかわからんしなぁ
xargs使う理由もわからんし。俺ならそんな使い方しない。
たくさんのDROP TABLE文で埋め尽くされたSQLファイルを作ってを実行するとかさぁ
いやテーブル名羅列するだけでいいのか
grepでテーブル名引っ張るとかあり得んし。
SHOW TABLES FROMはこの場合に適切なんだっけ?
ああ、思い出したINFORMATION SCHEMA.TABLESとかあったなぁ
ともかくシェルスクリプトでやることじゃないよね
なんのために問い合わせが得意なRDBMS使ってるのさ? 「LIKE」句を使って、テーブル名で絞り込む。
最後に「meta」で終わるテーブルだけを表示したい
mysql> SHOW TABLES FORM wordpress LIKE "%meta";
「mysql show tables」で検索! >>170, 171, 172
レスが遅くなって申し訳ありません。
CMSのインストール・削除のトライアンドエラーを
繰り返しているうちにテーブルが増えてきてしまった次第です。
やりたいことは、たくさんあるテーブルの中から
特定の接頭辞が付くテーブルだけを検索し削除したいです。
`drop table from 〇〇`でググるとかなりの割合の方が
bashでmysqlのコマンドを書いて力技で削除しているようでした。
当方もそれに習って色々試したのですが、
うまく動作せずに困っておりました。
こういった場合の無駄なくシンプルに削除するに
適切なコマンドはどうしたらよいのでしょうか? なんでわざわざ手間がかかることするかね?自動化したいんじゃないだろ?
>>172みたいに該当するテーブル一覧でもだして、テキストエディタでも使って
drop table from table1
drop table from table2
drop table from table3
とかいうSQL作って、それを実行すりゃいいやん
シンプルにしたいんだろ?なんでわざわざxargsとか使って複雑なものを作ろうとしてるんだ
自動化したいなら↑の内容を一つづつ自動化しろ。いっぺんにやろうとすんなよ。
1. テーブル一覧を、drop table from ○○にしやすいようにテーブル名のみの出力にしろ
2. テーブル名のリストをdrop table from ○○のリストに変換するスクリプトを作れ
3. そのスクリプトの出力をmysqlコマンドに流せ
これだけだろ
> ググるとかなりの割合の方が
ググるとかなりの割合の方が馬鹿なだけ >>174
詳しいアドバイスありがとうございます!
本当に目から鱗です。
レスを見て2分で解決しました。
bashで力技で何時間も悪戦苦闘していたのが
悲しくなるくらい呆気なさでした。
本当に的確なアドバイスありがとうございます! やってることが複雑になったと感じたら、最初に戻って考え直すことだ。 バッシュの教科書って本買おうとしたけど、どこでも売り切れてて人気みたい こういったケースの空白文字がある場合のワンライナーはどう書けばいいですか??
・特定のディレクトリの中にある大量のファイル
・ファイルは全て同じ拡張子(.mp3)
・拡張子の直前にランダムのID何文字か付いている(例 -48antiO81n5Dq)
・全てのIDを取り除きリネームしたい
自分で作成したのですが最後のmvで躓いています。。
空白文字があるとそこでファイル名を分割されてうまく動作しません。
```bash
find . -type f -name "*.mp3"|grep "\-[a-zA-Z0-9-]*.mp3$"|sed "s/\-[a-zA-Z0-9-]*.mp3$/.mp3/"|xargs -n2 mv
``` 慣れてる人ならともかくリネームとかいう取り返しのつかない作業を
findとxargsでやりたくないな
俺ならリスト生成してmvするわ
mv "aaa aaa-48antiO81n5Dq.mp3" "aaa aaa.mp3"
mv "bbb bbb-48antiO81n5Dq.mp3" "bbb bbb.mp3"
mv "ccc ccc-48antiO81n5Dq.mp3" "ccc ccc.mp3"
みたいなシェルスクリプトを生成して実行する
実行前に目視で確認できるし、場合によっては手動で修正すればいいし そもそもファイル名に空白が入ってなければ正しく動くのか?
aaa-48antiO81n5Dq.mp3
bbb-48antiO81n5Dq.mp3
というファイルがあったら sed の出力は
aaa.mp3
bbb.mp3
となるように思うのだが。いろいろつっこみたいが、とりあえず
find . -type f | xargs -d '\n' rename 's/-[a-zA-Z0-9-]*\.mp3$/.mp3/'
とするのが手っ取り早いと思う。
でもいきなりこんなことはしたくないね。
少なくともファイル名の衝突くらいはチェックしないと。 空白入るなら、ダブルクォートをエスケープして入れてやればいい、と。
そもそもxargs使わんといけんの?
ふつうにこんなんじゃだめか?
find . -type f -name "*.mp3"|grep "\-[a-zA-Z0-9-]*.mp3$" \
| while read i;do \
echo mv -v \"$i\" \"`echo $i|sed '"s/\-[a-zA-Z0-9-]*.mp3$/.mp3/'`\"; \
done
で、そもそもfind使うなら、-nameじゃなくて-regex使った方がよくない?
grepはそのためだよな?(ってまあ、俺もgrep使うような気がするけどw)
で、さらにfind使うなら、xargsよりは-execの方がベターだ。
で、そうすっとこれが多分模範回答
find . -type f -regex "\./\-[a-zA-Z0-9-]*.mp3$" \
-exec echo mv -v \"{}\" \"`echo {}|sed 's/\-[a-zA-Z0-9-]*.mp3$/.mp3/'`\" \;
で、いずれもmvの前にechoを入れてるので、よさげだったら、echoを削って祈ってw (´-`).。oO(>>1 は、いなくなったか…) if文で文字列を正規表現にマッチしたら抽出、という処理を作りたいのですが、
マッチしたら一つ目の文字列は抽出出来ましたが、二つ目以降マッチしたものが抽出できません
どうコードを書けば良いのでしょうか [[ foo-bar =~ (foo)-(bar) ]] && echo ${BASH_REMATCH[2]}
的な?
0にマッチ全体、カッコでグループ化すればn番目の部分マッチが1以降に入る
barが出るはず 推測だけど、一つ目のマッチだけ見えているんじゃなく、全体のマッチだけ見えてるんじゃないか?
配列変数を添字なしで参照すると0番目の要素が返る、よくある罠
$BASH_REMATCH
= ${BASH_REMATCH[0]}
= foo-bar
違ったらすまん nnn=111;mmm=0;echo $nnn | read mmm;echo $mmm
0
なんで? UIDとEUID を食い違いさせる方法って どんなのがありますか?