シェルスクリプト総合 その33

■ このスレッドは過去ログ倉庫に格納されています
2020/03/23(月) 01:12:30.31ID:TYte82vJ
シェルスクリプトに関する総合スレッドです。

全般
・荒しは無視しましょう。
・丁寧な姿勢を心掛けましょう。
・ネチケット(死語)を意識しましょう。
・「○○(他の言語)でいいやん」は禁止。他のスレに行ってください。

シェルスクリプト総合 その32
https://mevius.5ch.net/test/read.cgi/tech/1571929725/
2020/08/10(月) 16:59:38.66ID:BcFTAJq0
zshって:コマンドが遅いと思ったら、:という名前の関数を定義できるから
何もしないコマンドではなく関数呼び出しのようになってるんだろうな
めんどくさいね
778デフォルトの名無しさん
垢版 |
2020/08/10(月) 17:59:39.62ID:IQ3fIsH1
絵文字→数値文字参照に変換したいんだけどシェルだけじゃ無理?
たとえば「😀」であったら「&# 128512;」みたいな
nkfで数値文字参照→絵文字の逆パターンはできるっぽいけど
2020/08/10(月) 18:12:59.63ID:jBTjAApo
printf '&#%d;' \'
2020/08/10(月) 18:18:15.92ID:BcFTAJq0
>778
できるよ

#!/bin/bash
unk="??" # ← うんこの絵文字
printf '%x' "'$unk" # 1f4a9

ただしbashのようにUnicode対応してるシェルじゃないと駄目
dashのように対応してないシェルだと1バイトずつの処理になるからから
UTF-8 → コードポイントへの変換処理を自前でやる必要がある

あと文字ではなく文字列の場合は1文字ずつループする必要があるね
これもbashだったら簡単だけど、dashとかだと苦労する。
dash等の場合パフォーマンスの点からodコマンドで
8進数化して処理したほうが速いかもしれない
どちらにしろまあ手間がかかる
2020/08/10(月) 18:25:22.89ID:HYtJuMAc
こんにちは

PowerShellだと自作のhoge.ps1ファイルを実行すれば
hoge.ps1に定義していた関数が使えるようになりますが

Macで同じように自作のpiyo.shに書いて,ターミナルから実行して,
piyo.shに定義していた関数をその後も有効にすることはできないでしょうか

PowerShellと同じ感覚でtest.shに

#!/bin/bash
function hello(){
echo "Hello, World!
}

と書いて実行したら,ターミナル上でその後も関数helloが有効になると思っていたのですが・・・
初心者(今日からはじめました)のでなにもわかってないと思いますが
782デフォルトの名無しさん
垢版 |
2020/08/10(月) 18:27:22.34ID:IQ3fIsH1
>>779
>>780
おお、できた!
printfで完結するんだね
メインのシェルはbashだから大丈夫
ありがとう!
2020/08/10(月) 18:31:59.86ID:BcFTAJq0
>>781
source(または . コマンド)で読み込む

シェルスクリプトを「実行」した場合は
新たにプロセスが作られて実行される。

今使ってるシェルでつかえるようにするには
現在のシェルに読み込まなくてはいけない
それがsourceコマンド

でもまあ個人的には外部シェルスクリプトにするほうが
便利な気もするけどな
2020/08/10(月) 18:36:45.96ID:HYtJuMAc
ありがとうございました!
2020/08/10(月) 18:36:55.03ID:BcFTAJq0
printf '%x' "'$unk" # 1f4a9

ところでこの シングルクォート を頭につけるって
仕様どこのバカが考えたんだろうな?
このせいで最初の一文字しか変換できず
文字列を文字コードにすることができなくなってる

フォーマット書式を拡張して、例えばこんなふうにしていれば
文字列を全体を変換するとかできただろうに。今からでも遅くはないが
printf '%@x' "$unk"
2020/08/10(月) 18:49:27.63ID:BcFTAJq0
ちゃんとテストしてないけど、文字列全部をコードポイントにする方法

while [ "$str" ]; do
 printf '%x ' "'$str"
 str=${str#?} # 頭一文字を削除
done

多分動くと思うけどprintfを文字の数だけ実行しないといけないのがダサい(遅い)
bashだったら、頭から文字を削らなくても ${str:N:1} でできるはず
どちらにしろprintfの実行回数は減らせないが

ここから絵文字のみをコードポイントにするには
コードポイントの判定が必要になるので・・・
codepoint=$(printf '%x' "'$str")
これはサブシェル使ってるから更に遅くなる(ため息)
パイプ使って処理するのがまだましかねぇ

while [ "$str" ]; do
 printf '%x\n' "'$str"
 str=${str#?} # 頭一文字を削除
done | while IFS= read -r codepoint; do
 # そのまま出力するか、実体参照で出力するか判定して切り分ける
done

めんどくせーなw
2020/08/10(月) 19:09:20.89ID:t4rZM551
だったらPerlを使えば。
2020/08/10(月) 19:10:29.77ID:BcFTAJq0
>>787
そのネタは飽きた
2020/08/10(月) 20:01:35.10ID:jBTjAApo
いつものRubyおじさんは盆休みか
2020/08/10(月) 21:47:25.96ID:H4x6U7o8
そういう場合はバラすコマンドを書くんだよ
printfなんて引数が書式から溢れたら繰り返すという独特の仕様なんだし
2020/08/10(月) 22:04:46.97ID:wrD0HyDw
>>790
そうすると今度は引数が多すぎますってなるんだよな
また全てを実体参照にしないなら、書式も動的に組み立てる必要がある
一体どのアルゴリズムが一番速いのか?
なかなかうまく行かないもんだよね
2020/08/10(月) 23:58:47.58ID:t4rZM551
>>791
行にばらしてから、xargsでまとめればなんとか?

なお、速さを心配するならPerlで!
2020/08/11(火) 06:27:29.80ID:imudTDmO
👨‍👨‍👧‍👧
2020/08/11(火) 14:02:41.21ID:oiMKju9F
>>782
一応純POSIXでもできる。
https://gist.github.com/cmplstofB/0b0ce2bf052b3bb64d091fc83504fc32#file-u8dec-sh
2020/08/11(火) 15:00:36.80ID:6EF+liXG
>>794
シェルつーか、sedやな。w
2020/08/11(火) 17:50:39.44ID:K2Zt4r5r
printfもシェルつーかprintfコマンドやな。という言い方もできる
ほとんどはprintfはビルトインコマンドだからシェルの一部と言えるが
なんとmkshではビルトインではないのだ
だからprintfを多用するとmkshでは遅くなる
2020/08/11(火) 18:15:17.47ID:lw0B26+i
速度速度言うなら...w
まあ、マジでそう思わないこともない
2020/08/11(火) 18:20:09.85ID:K2Zt4r5r
言語(ツール)を選ぶ理由は速度が第一じゃないからね

なにか理由があって言語(ツール)を選ぶ
その上で(極端に)遅くなる場合ってのは
知っておいたほうがいい

無知で極端に遅くしておいて、自分が悪いのに
言語(ツール)のせいにするのは愚か者
2020/08/11(火) 22:40:08.94ID:wY/KrlTt
一人で妄想して馬鹿にしてる感じ、誰のことを言っているのだが
2020/08/11(火) 22:47:03.84ID:ZSHW8utc
誰も聞いてないことをで自己満してる
承認欲求が激しいんだろうな
2020/08/12(水) 00:31:12.05ID:EZbfglBp
外部コマンドをビルトイン化できるらしいがどんな用途で使うんだ
日頃使ってるechoは速度重視だからシェルに内蔵してるってのは分かるが
2020/08/12(水) 01:05:34.01ID:IJKCUlyt
>>801
細かい用途はいくつか思いつくし、思いついてるだろうけど
使うか?って聞かれたら使わないだろうなって思うものばかりだよ
2020/08/12(水) 06:01:38.86ID:IJKCUlyt
lessコマンドひでぇw

-? -# -~ -" とかいうオプションがあるw
2020/08/12(水) 11:54:29.64ID:dh92Tz6A
.shファイルの実行はずっと脳死で「sh test.sh」とかでやってたけどそれだとPOSIXの関係で目的通り動いてくれないコマンドもあるのか
ログイン時のデフォルトシェルがbashでもshで叩いてしまうと意味がないと
これからは「bash test.sh」 とかでやるようにするけどshで叩く癖が抜けるまでしばらくかかりそう…
2020/08/12(水) 12:35:47.57ID:RMBTHnXK
>>804
chmod +xして#!をちゃんと書いたら?
わざわざshやらbashやらから打ち込まなくても。
2020/08/12(水) 13:23:38.06ID:dh92Tz6A
>>805
実行権ってそんな便利なことができるのか
今までよく分からなかったからスルーしてたorz
#!もちゃんと書いてshとか抜きで無事実行できました
ありがとう
2020/08/12(水) 15:14:39.87ID:obuPMR8V
スレチでしたら申し訳ないです
どこで質問したらいいのか分かりませんでした

curlで取得したhtmlソースからページのタイトルを取得したいです

curl "https://ja.wikipedia.org/wiki/"; | nkf -w | grep -oP '(?<=<title>)(.+)(?=</title>)'

こんな感じで<title>タグに挟まれた文字列を正規表現で抽出すればできそうなのですが、wiki等の一部サイトではgrepで抽出できません
googleやyahooはできました

文字コードがShift-JISなのが問題だと思いますがnkfで変換してあるのになぜできないのかわかりません

どうすれば抽出できますか?
2020/08/12(水) 15:43:49.03ID:bbgn0zyb
curl -Ls 'https://ja.wikipedia.org/wiki/' | ...

で良いんじゃない
2020/08/12(水) 16:10:52.81ID:HozojyCs
pup使うとCSSセレクター使えるから簡単だよ

curl -Ls "https://ja.wikipedia.org/wiki/"; | pup ‘title text{}’
810デフォルトの名無しさん
垢版 |
2020/08/12(水) 18:12:06.06ID:6RKl90uC
ファイル名が「20200812.txt」と、日付が入っているとします。
7日前の古いファイルを削除したいと思い、

oldfile=`date -d "7 day ago" +'%Y%m%d'`
rm -f /home/test/public_html/$oldfile.txt

としたのですが、「20200805.txt」が削除されません。

oldfile=20200805
rm -f /home/test/public_html/$oldfile.txt

というように直接日付を書けば削除されます。
何が原因でしょうか?(パーミッションは問題ないです)
811デフォルトの名無しさん
垢版 |
2020/08/12(水) 18:17:55.09ID:hhSLRkul
$oldfileの中身確認した時点でわかるだろ・・
2020/08/12(水) 18:20:34.06ID:6RKl90uC
echo `date -d "7 day ago" +'%Y%m%d'`
というコマンドを実行すると、「20200805」となります。
なので、$oldfileに代入されていると思うのですが、
なぜかシェルスクリプトからは実行されない?みたいです。
なので、書き方が悪いと思っているのですが・・・
2020/08/12(水) 18:27:02.02ID:RMBTHnXK
>>810
olddateは正しいとして。

パーミッションは本当に適切か?
そのファイルまでのディレクトリは全部見えるか?
親ディレクトリにwは付いてるか?

ユーザーは違わないか?
もしcronなどから実行してたら、実際のユーザーが違うかも?
2020/08/12(水) 18:37:18.23ID:6RKl90uC
>>813
>>810の、下の書き方(日付を直接書く)場合だと削除されるので、
パーミッションやらユーザーやらは正しいと思います。
2020/08/12(水) 18:57:36.02ID:o8GAAC7N
共に、
echo rm -f /home/test/public_html/$oldfile.txt

echo rm -f /home/test/public_html/$oldfile.txt | od
で出して同じか見てみ。違うんだろうとしか思えんけど
2020/08/12(水) 20:47:24.78ID:RMBTHnXK
そもそも、エラーメッセージは出てないんか?
パスがないとかパーミッションがないとか。
2020/08/12(水) 21:57:38.22ID:obuPMR8V
>>808
>>809
Lオプションでできました
pupの情報もありがとうございます
2020/08/13(木) 05:33:16.94ID:b3k2BUbg
oldfile=`date -d "7 day ago" +'%Y%m%d'`
echo $oldfile
20200806

# -x は、16進数。big endian で表示する
echo $oldfile | od -x --endian=big
3230 3230 3038 3036 0a00

0a00 が入っている!
2020/08/13(木) 05:43:37.21ID:b3k2BUbg
>>807
Ruby なら、静的なページを、Nokogiri で、スクレイピングできる。
ただし、Ajax を使う動的なページは、sleep するか、Selenium Webdriver を使う

require 'nokogiri'

html = `curl http://www.example.com/`

doc = Nokogiri::HTML( html )

elements = doc.css( "h1" )
puts elements.first.content #=> Example Domain
2020/08/13(木) 05:48:49.75ID:AjBI18lb
0a 付けてるのは echo
-x
16 進 short として出力する。 -t x2 と等価。
short として出力するためにpaddingとしての 00
echo 20200806 | od -x --endian=big
しても同じだろうが
2020/08/13(木) 05:54:05.59ID:AjBI18lb
>>819
>>809と違いはなさげ。pupというのを新しく入れるのが障壁でないようだし
他人にシェルスクリプトのスレでRubyを勧めるぐらいなら、お前は基本的なことを勉強するのが先だw
822818
垢版 |
2020/08/13(木) 07:27:56.07ID:b3k2BUbg
漏れは、Windows 10, WSL, Ubuntu 18.04 だけど、

which pup
無し

apt-cache show pup
パッケージ pup が見つかりません

oldfile=`date -d "7 day ago" +'%Y%m%d'`

echo $oldfile | od -x --endian=big
3230 3230 3038 3036 0a00

echo $oldfile.txt | od -x --endian=big
3230 3230 3038 3036 2e74 7874 0a00

確かに、0a00 は、echo が付けているだけだった
2020/08/13(木) 08:14:35.56ID:r+Myq/6D
> rm -f /home/test/public_html/$oldfile.txt
>
> としたのですが、「20200805.txt」が削除されません。

-f つけなければなにかわかるだろ
2020/08/13(木) 10:30:46.90ID:u1yLpjcC
>>810
上の方法でもこっちでは成功したから、
なんか全く別の所でひっかかってる気がするんだけど
とりあえず
rm ~/"public_html/$(date -d '7 days ago' +'%Y%m%d')"
こうしてみて。
2020/08/13(木) 11:03:45.75ID:HLH3bdVq
>>823
エラーがなくなるだけだろ。
2020/08/13(木) 11:07:31.64ID:i+RlWr/H
>>825
そう考えてるなら理解力がない
827810
垢版 |
2020/08/13(木) 11:42:16.52ID:1yPigLiW
>>810です。みなさん色々ありがとうございます。
原因はわかりませんが、以下のコマンドで削除されました!

oldfile=`date -v-7d +"%Y%m%d"`
rm -f /home/test/public_html/$oldfile.txt

サーバーはFreeBSDなのですが、
サーバー的な問題があったのかもしれません
2020/08/13(木) 12:20:55.98ID:i+RlWr/H
ほらみろ-fをなくしたらわかる話だっただろうが
2020/08/13(木) 16:42:10.47ID:UJyiXERu
>>822
パッケージに無くても入れらるんだぞ。パッケージになないようだけどな

>確かに、0a00 は、echo が付けているだけだった
0a な。 00 を付けてるといえば付けてるのは od な
2020/08/13(木) 19:04:38.45ID:/leUQEag
while ここでbreak使うのはOkなのだろうか?; do
:
done
2020/08/15(土) 08:39:14.46ID:Ob8esEzA
継続行の後にコメントってかけないの?
2020/08/15(土) 13:15:03.53ID:sQULdK+x
書けたとしても書かない方がいいだろうな
可読性が下がるから
2020/08/15(土) 17:32:34.73ID:ODJGcA2C
>>831
書けるんじゃないの?
2020/08/15(土) 19:07:09.82ID:Ob8esEzA
え?どうやって?

foo \ # comment
foo # commnet \

どっちも無理なんだけど?
2020/08/15(土) 20:54:12.94ID:ODJGcA2C
>>834
前者は継続行ではなくエスケープ。
後者は、その次に続く。
2020/08/15(土) 22:14:34.07ID:Ob8esEzA
>>835
そんなことは聞いてないよ
2020/08/15(土) 22:15:49.30ID:/M/D7F5G
printf “―-こんにちわ―-“

みたくprintfにハイフンから始まる文字列を出力させようとするとエラー出るんですけどどうにかならいですかね?
echo使えば解決ですけど
2020/08/15(土) 22:17:46.31ID:Ob8esEzA
print '%s'
2020/08/15(土) 22:19:39.71ID:qj/CORtd
>>837
printf -- “―-こんにちわ―-“
2020/08/15(土) 22:23:58.73ID:/M/D7F5G
>>838
>>839
おー、これでできました
ありがとうございます!
2020/08/15(土) 22:33:10.73ID:ODJGcA2C
>>836
じゃあ継続行を勘違いしてるんやろ。
2020/08/15(土) 23:01:28.72ID:Ob8esEzA
>>841
すみませんが、質問内容は最初に書いたとおり
「継続行の後にコメントってかけないの?」です
2020/08/15(土) 23:36:06.37ID:8MGPAd1y
以下のようなヒアドキュメントを使用して、sshコマンドで複数コマンドの出力結果をすべてファイルに出力したい場合、どのようにしたら可能でしょうか?

ssh -t -t ユーザ@IP <<EOC
 コマンド1
 コマンド2
 コマンド3
 exit
EOC

ちょっと試す環境が無いのですが、以下のように1行目をリダイレクトすれば可能でしょうか?
ssh -t -t ユーザ@IP <<EOC >>出力ファイル
2020/08/16(日) 00:19:03.11ID:YKxJCnVG
>>842
commandline \
# 継続行の後。

書けるやろ。
ほかの解釈があるか?
2020/08/16(日) 00:19:53.88ID:YKxJCnVG
>>843
環境がないのになぜ聞く?
2020/08/16(日) 00:35:02.24ID:1j/DClPj
なんやねんw
2020/08/16(日) 02:27:19.62ID:beccON1S
>>845
気軽に試せるテスト用の環境がないので作って本番運用してみるしかないのですが、分かれば事前に確認したく
2020/08/16(日) 02:33:52.97ID:XbVXxig+
>>844
あんた面倒くさい人だっていわれたことあるでしょ?
何を言うべきか最初から気付いているのに
わざとそれをいわずに回りくどい言い方しかしない
あんたコミュニケーション能力ないよ
2020/08/16(日) 02:34:46.65ID:YKxJCnVG
>>847
Dockerを試せば。
たぶんなにかと役に立つのでは。
2020/08/16(日) 02:35:16.56ID:hHqe5wIQ
>>847
したく…なんだよw
2020/08/16(日) 02:35:35.89ID:1G6F2nAS
「どのようにしたら可能でしょうか?」

レス「環境がないのになぜ聞く?」

これだもんなw
2020/08/16(日) 02:37:08.19ID:1G6F2nAS
>>850
こういうやつ、ほんとコミュニケーションに向いてないなw

「〜したく。」という表現について
https://oshiete.goo.ne.jp/qa/3612600.html
2020/08/16(日) 02:37:51.28ID:YKxJCnVG
>>848
バカには難しかったね。w
おきのどく。
2020/08/16(日) 02:38:05.03ID:1G6F2nAS
まーた始まった
2020/08/16(日) 02:40:15.48ID:YKxJCnVG
>>851
じゃあおまえがこたえてやれよ。
くちのききかたのことしかいえないの?w
2020/08/16(日) 02:42:05.20ID:1G6F2nAS
>>843
それで可能


>>855
答えましたが?w
たった5文字で終わることを長くさせてるのは自分だって自覚しような
2020/08/16(日) 02:42:18.69ID:hHqe5wIQ
>>852
本当にそうだよね、そのリンクで挙げられている会社内で使えよって話
2020/08/16(日) 02:43:10.98ID:1G6F2nAS
わざと、世間でも使われてるって書いてあるのみて、無視してるんだろうなーw
2020/08/16(日) 02:44:34.09ID:hHqe5wIQ
>>858
よく読めw
2020/08/16(日) 02:45:33.86ID:hHqe5wIQ
散々否定されてるだろwww
2020/08/16(日) 02:45:49.62ID:1G6F2nAS
ベストアンサーより
> ”頂きたく””致したく””お願いしたく”といった表現は、昔からよく使う会社とそうでもない会社があるようです。
2020/08/16(日) 02:46:16.68ID:hHqe5wIQ
使っている会社があるけどおかしいよねってソースだろそれ
2020/08/16(日) 02:46:30.85ID:hHqe5wIQ
まあ日立なんだけど
2020/08/16(日) 02:47:50.55ID:1G6F2nAS
>>862
ビジネスとしておかしい、マナーとしておかしいけど、使われてるって話だろ?
ここビジネスか?w
2020/08/16(日) 02:48:39.56ID:hHqe5wIQ
>>864
そのおかしい言葉をおかしいと思わずに使っている恥ずかしいやつって見られるだけだから別にいいと思うよ!
2020/08/16(日) 02:49:02.10ID:hHqe5wIQ
頑張って広めてね!応援してるよー
2020/08/16(日) 02:49:36.40ID:XtZ0e6Es
また日立語かよ、きも
2020/08/16(日) 02:51:41.90ID:1G6F2nAS
広まってるからこうやってググって見つかるのにw
ああ、そうか使われてるって知らないって話だったな
2020/08/16(日) 02:53:03.05ID:hHqe5wIQ
>>868
うんにゃ、知ってるよ
おかしな言葉として有名だからね
2020/08/16(日) 02:55:17.21ID:hHqe5wIQ
>>868
ググって見つかる言葉なら正解だよね!わざわざググってくれた君の行動に行動に敬意を評したく
2020/08/16(日) 02:56:14.55ID:1G6F2nAS
1. 言葉がおかしいと知ってる
2. 言葉がおかしいとレスすればいい
3. それ以前に、正しい言葉を知ってるんだから
脳内で補間して、本当にすべきレスをすればいい

実際に返したレス→「したく…なんだよw」


な?コミュニケーション能力ないだろ?w
2020/08/16(日) 02:59:10.06ID:hHqe5wIQ
>>871
変なとこでぶった切ってるから何が言いたいんだ?もっとまともな日本語使えよってツッコミでしょ?
もう少しまともな思考をしてもらいたく
2020/08/16(日) 03:00:17.69ID:hHqe5wIQ
>>871
日立語をぜひ広めてもらいたく
2020/08/16(日) 03:01:10.81ID:1G6F2nAS
こういうナチュラルに嫌がらせをするやつっているよなw

「すいませーん。ちょっと今いいですかー?」

「え?吸いませんってなに?タバコ?タバコ吸わない宣言でもしてるの?w」


はぁ、疲れつやつだ。こいつ相手だと話が進まない。ってなる。
2020/08/16(日) 03:03:08.25ID:hHqe5wIQ
>>874
まったく比較になっていない例えを持ち出してくるやつっているよねー。こいつ相手だと話が進まない。ってなる。同僚に同情したく。
2020/08/16(日) 03:04:12.32ID:hHqe5wIQ
>>874
疲れながら構ってくれてありがとう。感謝したく
2020/08/16(日) 03:05:32.81ID:1G6F2nAS
「したく」って言葉がよっぽど気に触ったようだw
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況