一個bash腳本的問題

sh/bash/dash/ksh/zsh等Shell脚本
回复
linuxmm9
帖子: 147
注册时间: 2017-08-19 10:12
系统: linux
送出感谢: 45 次
接收感谢: 0

一個bash腳本的問題

#1

帖子 linuxmm9 » 2019-04-26 20:18

abc="sed -i "123 ) 456 7 8" /home/123"

bash裡有空格用雙引號 但是上面這個例子中數字兩邊用雙引號就會提示出錯 請問正確的格式該怎麼解
头像
astolia
论坛版主
帖子: 4417
注册时间: 2008-09-18 13:11
送出感谢: 1 次
接收感谢: 739 次

Re: 一個bash腳本的問題

#2

帖子 astolia » 2019-04-26 22:34

如果就是纯文本的话,直接用单引号就够了

代码: 全选

abc='sed -i "123 ) 456 7 8" /home/123'
单双引号混用来拼接字符串也是没问题的

代码: 全选

abc="sed -i "'"'"123 ) 456 7 8"'"'" /home/123"
这些用户感谢了作者 astolia 于这个帖子:
linuxmm9 (2019-04-27 11:26)
评价: 3.7%
linuxmm9
帖子: 147
注册时间: 2017-08-19 10:12
系统: linux
送出感谢: 45 次
接收感谢: 0

Re: 一個bash腳本的問題

#3

帖子 linuxmm9 » 2019-04-27 11:25

astolia 写了:
2019-04-26 22:34
如果就是纯文本的话,直接用单引号就够了

代码: 全选

abc='sed -i "123 ) 456 7 8" /home/123'
单双引号混用来拼接字符串也是没问题的

代码: 全选

abc="sed -i "'"'"123 ) 456 7 8"'"'" /home/123"
謝謝

另外還想問一個問題 怎樣把幾個命令一起賦值給一個變量 格式不會寫
linuxmm9
帖子: 147
注册时间: 2017-08-19 10:12
系统: linux
送出感谢: 45 次
接收感谢: 0

Re: 一個bash腳本的問題

#4

帖子 linuxmm9 » 2019-04-27 11:37

還有兩個問題

abc="touch /xxx/xxx/xxx/{123,234,345}"

我想建立123,234,345這幾個文件 但是結果只建立了{123,234,345}

還是沒搞懂這個格式啊

另外就是
abc="touch /xxx/xxx/xxx/dd ; touch /xxx/xxx/xxx/6 ; chmod -R 777 /xxx/xxx/xxx/66"
只能識別touch命令 無法完成這三個命令
头像
astolia
论坛版主
帖子: 4417
注册时间: 2008-09-18 13:11
送出感谢: 1 次
接收感谢: 739 次

Re: 一個bash腳本的問題

#5

帖子 astolia » 2019-04-27 16:53

linuxmm9 写了:
2019-04-27 11:37
abc="touch /xxx/xxx/xxx/{123,234,345}"
我想建立123,234,345這幾個文件 但是結果只建立了{123,234,345}
我不清楚你是怎么去执行touch的,是直接$abc这样?
看得出来你不了解bash的处理顺序。简单来说,处理{123,234,345}会在处理$abc之前,一旦执行到把$abc展开为touch /xxx/xxx/xxx/{123,234,345}这步时,就不会再去管展开后的文本中的{}部分了。
具体顺序可以阅读这篇 http://tldp.org/LDP/Bash-Beginners-Guid ... 03_04.html
linuxmm9 写了:
2019-04-27 11:37
另外就是
abc="touch /xxx/xxx/xxx/dd ; touch /xxx/xxx/xxx/6 ; chmod -R 777 /xxx/xxx/xxx/66"
只能識別touch命令 無法完成這三個命令
原因同上,bash对命令根据;来分隔更是在最初就完成了的。当执行到$abc时,第一个touch后面的全都视作touch的参数,不会再去当成多条命令处理了。

可以通过eval命令来让bash再次处理

代码: 全选

abc="touch /tmp/{123,234,345}"
eval $abc
但eval很容易被误用,导致各种命令注入式攻击。就你的“一次执行多个命令”的需求,最合理的做法是用自定义函数功能。

代码: 全选

abc() {
touch /xxx/xxx/xxx/dd
touch /xxx/xxx/xxx/6
chmod -R 777 /xxx/xxx/xxx/66
}
abc
这些用户感谢了作者 astolia 于这个帖子:
linuxmm9 (2019-04-29 22:21)
评价: 3.7%
linuxmm9
帖子: 147
注册时间: 2017-08-19 10:12
系统: linux
送出感谢: 45 次
接收感谢: 0

Re: 一個bash腳本的問題

#6

帖子 linuxmm9 » 2019-04-27 17:57

但eval很容易被误用,导致各种命令注入式攻击。就你的“一次执行多个命令”的需求,最合理的做法是用自定义函数功能。

代码: 全选

abc() {
touch /xxx/xxx/xxx/dd
touch /xxx/xxx/xxx/6
chmod -R 777 /xxx/xxx/xxx/66
}
abc
非常感謝 我想這就是我想要的 不過又有一個新問題 我是想把abc寫到case裡交互時使用 但是我運行腳本時 就執行了那幾個命令 這個又該怎麼做呢
linuxmm9
帖子: 147
注册时间: 2017-08-19 10:12
系统: linux
送出感谢: 45 次
接收感谢: 0

Re: 一個bash腳本的問題

#7

帖子 linuxmm9 » 2019-04-27 18:06

對不起 我真的是不懂腳本程序 請不要見怪

我剛才把自定義函數放到case裡 這樣就不會自動執行那幾個命令了 不知道這樣是不是正確做法
linuxmm9
帖子: 147
注册时间: 2017-08-19 10:12
系统: linux
送出感谢: 45 次
接收感谢: 0

Re: 一個bash腳本的問題

#8

帖子 linuxmm9 » 2019-04-27 18:10

read -n1 -t 6 -p ": " answer

case $answer in
0)
abc() {
touch /xxx/xxx/xxx/dd
touch /xxx/xxx/xxx/6
chmod -R 777 /xxx/xxx/xxx/66
}
abc

$abc && $aplay_ 2>/dev/null
#clear
echo "end"
;;
1)
$xxx && $xxx && $xxx && $xxx $aplay_ 2>/dev/null
clear
echo "[])"
;;
2)
$xxx && $aplay_ 2>/dev/null
;;
*)
clear
;;
esac



#sed -i '82s/^#//' /home/atar/.conkyrc

exit 0
头像
astolia
论坛版主
帖子: 4417
注册时间: 2008-09-18 13:11
送出感谢: 1 次
接收感谢: 739 次

Re: 一個bash腳本的問題

#9

帖子 astolia » 2019-04-28 20:55

建议你找本shell编程的书,系统地学一下。
上面的代码太过混乱,搞不懂你到底想做什么

代码: 全选

abc() {
  touch /xxx/xxx/xxx/dd
  touch /xxx/xxx/xxx/6
  chmod -R 777 /xxx/xxx/xxx/66
}
这个是自定义函数abc的定义部分,应该放在case外面

代码: 全选

abc
这样就是直接调用上面定义了的abc,建议把你原来所有的$abc这种全部改成自定义函数形式。

另外光像上面那样写,函数的返回值永远是0,无法判断里面的命令执行成功与否,可以加上if和return来对不同的情况返回不同的值,比如像下面这样

代码: 全选

abc() {
  touch /xxx/xxx/xxx/dd && \
  touch /xxx/xxx/xxx/6 && \
  chmod -R 777 /xxx/xxx/xxx/66
  return $?
}
只有当touch和chmod都成功才返回0,否则返回出错的exit code
这些用户感谢了作者 astolia 于这个帖子:
linuxmm9 (2019-04-29 22:20)
评价: 3.7%
linuxmm9
帖子: 147
注册时间: 2017-08-19 10:12
系统: linux
送出感谢: 45 次
接收感谢: 0

Re: 一個bash腳本的問題

#10

帖子 linuxmm9 » 2019-04-29 12:27

astolia 写了:
2019-04-28 20:55
建议你找本shell编程的书,系统地学一下。
上面的代码太过混乱,搞不懂你到底想做什么

代码: 全选

abc() {
  touch /xxx/xxx/xxx/dd
  touch /xxx/xxx/xxx/6
  chmod -R 777 /xxx/xxx/xxx/66
}
这个是自定义函数abc的定义部分,应该放在case外面

代码: 全选

abc
这样就是直接调用上面定义了的abc,建议把你原来所有的$abc这种全部改成自定义函数形式。

另外光像上面那样写,函数的返回值永远是0,无法判断里面的命令执行成功与否,可以加上if和return来对不同的情况返回不同的值,比如像下面这样

代码: 全选

abc() {
  touch /xxx/xxx/xxx/dd && \
  touch /xxx/xxx/xxx/6 && \
  chmod -R 777 /xxx/xxx/xxx/66
  return $?
}
只有当touch和chmod都成功才返回0,否则返回出错的exit code
好的 我會系統學習bash 謝謝你

另外 在這裡我還想問問 如你所說在函數裡加入 return $? 我不知道具體是什麼意思 我也查了資料 但是感覺不的哦到特別的用處

還有就是我可以這麼寫嗎
abc() {
touch /xxx/xxx/xxx/dd && \
touch /xxx/xxx/xxx/6 && \
chmod -R 777 /xxx/xxx/xxx/66 && clear
}
如果沒問題就清屏
头像
astolia
论坛版主
帖子: 4417
注册时间: 2008-09-18 13:11
送出感谢: 1 次
接收感谢: 739 次

Re: 一個bash腳本的問題

#11

帖子 astolia » 2019-04-29 21:20

linuxmm9 写了:
2019-04-29 12:27

好的 我會系統學習bash 謝謝你

另外 在這裡我還想問問 如你所說在函數裡加入 return $? 我不知道具體是什麼意思 我也查了資料 但是感覺不的哦到特別的用處

還有就是我可以這麼寫嗎
abc() {
touch /xxx/xxx/xxx/dd && \
touch /xxx/xxx/xxx/6 && \
chmod -R 777 /xxx/xxx/xxx/66 && clear
}
如果沒問題就清屏
运行任何一个程序/命令,结束后会有一个退出码(exit code)来指示运行结果。0代表成功,非0值代表出错。
xx && yy的实际执行方式就是只有当xx的退出码为0时,才去执行yy。同理xx || yy是当xx的退出码不为0时才去执行yy

$?这个就是指上一个程序/命令的退出码。如果是自定义函数,它的返回值(默认为0)就等同于退出码的作用。具体到abc()就是两个touch和chmod如果都运行成功,则返回chmod的退出码0,否则返回它们中第一个出错的命令的退出码。

这样一来,就能从函数的返回值来确定函数中的命令是否执行成功,然后根据成功与否来进行下一步的操作。如果像你那样只是清屏,abc && aplay这种会在abc中的命令执行出错后仍然运行aplay,可能会引发进一步的错误。
这些用户感谢了作者 astolia 于这个帖子:
linuxmm9 (2019-04-29 22:20)
评价: 3.7%
linuxmm9
帖子: 147
注册时间: 2017-08-19 10:12
系统: linux
送出感谢: 45 次
接收感谢: 0

Re: 一個bash腳本的問題

#12

帖子 linuxmm9 » 2019-04-29 22:20

astolia 写了:
2019-04-29 21:20
linuxmm9 写了:
2019-04-29 12:27

好的 我會系統學習bash 謝謝你

另外 在這裡我還想問問 如你所說在函數裡加入 return $? 我不知道具體是什麼意思 我也查了資料 但是感覺不的哦到特別的用處

還有就是我可以這麼寫嗎
abc() {
touch /xxx/xxx/xxx/dd && \
touch /xxx/xxx/xxx/6 && \
chmod -R 777 /xxx/xxx/xxx/66 && clear
}
如果沒問題就清屏
运行任何一个程序/命令,结束后会有一个退出码(exit code)来指示运行结果。0代表成功,非0值代表出错。
xx && yy的实际执行方式就是只有当xx的退出码为0时,才去执行yy。同理xx || yy是当xx的退出码不为0时才去执行yy

$?这个就是指上一个程序/命令的退出码。如果是自定义函数,它的返回值(默认为0)就等同于退出码的作用。具体到abc()就是两个touch和chmod如果都运行成功,则返回chmod的退出码0,否则返回它们中第一个出错的命令的退出码。

这样一来,就能从函数的返回值来确定函数中的命令是否执行成功,然后根据成功与否来进行下一步的操作。如果像你那样只是清屏,abc && aplay这种会在abc中的命令执行出错后仍然运行aplay,可能会引发进一步的错误。
好的 非常感謝您耐心的解答和分析 :Smile
回复

回到 “Shell脚本”