คำสั่งไม่พบข้อผิดพลาดในการกำหนดตัวแปร Bash


520

ฉันมีสคริปต์นี้ชื่อ test.sh:

#!/bin/bash
STR = "Hello World"
echo $STR

เมื่อฉันวิ่ง sh test.shฉันจะได้รับสิ่งนี้:

test.sh: line 2: STR: command not found

ผมทำอะไรผิดหรือเปล่า? ฉันมองไปที่พื้นฐานมาก / ผู้เริ่มต้นบทเรียนการเขียนสคริปต์ทุบตีออนไลน์และนี่คือวิธีที่พวกเขาพูดเพื่อประกาศตัวแปร ... ดังนั้นฉันไม่แน่ใจว่าสิ่งที่ฉันทำผิด

ฉันใช้ Ubuntu Server 9.10 /bin/bashและใช่ทุบตีตั้งอยู่ที่


49
ฉันดีใจที่คุณถามคำถามคุณไม่ใช่คนเดียวที่ทุบตี noob!
มิลเลอร์กอริลลา

6
ขอบคุณที่ถามคำถาม นี่ไม่ใช่คำถามที่จะต้องอาย ฉันทำงานตอนดึกที่สำนักงาน & ไม่มีผู้เชี่ยวชาญทุบตีอยู่รอบตัวฉันเพื่อตอบคำถามนี้
Adway Lele

3
วันนี้ (เกือบเจ็ดปีต่อมา!) มีตัวกรอง / ตัววิเคราะห์ FOSS ที่เรียกว่าshellcheckที่จะตรวจหาอัตโนมัติและปัญหาไวยากรณ์ทั่วไปอื่น ๆ สามารถใช้ออนไลน์หรือติดตั้งออฟไลน์และรวมอยู่ในโปรแกรมแก้ไขของคุณ
ผู้ชายคนอื่นนั่น


ฉันขอแนะนำให้คุณใช้: #!/usr/bin/env bashแทนที่จะใส่โดยตรง#!/bin/bashเว้นแต่คุณจะแน่ใจว่าbashเป็น/binเพราะคำตอบนี้: stackoverflow.com/a/21613044/3589567
Alejandro Blasco

คำตอบ:


928

คุณไม่สามารถเว้นวรรครอบเครื่องหมาย '=' ของคุณ

เมื่อคุณเขียน:

STR = "foo"

bash พยายามเรียกใช้คำสั่งชื่อ STR พร้อมอาร์กิวเมนต์ 2 ตัว (the strings '=' และ 'foo')

เมื่อคุณเขียน:

STR =foo

bash พยายามเรียกใช้คำสั่งชื่อ STR พร้อม 1 อาร์กิวเมนต์ (สตริง '= foo')

เมื่อคุณเขียน:

STR= foo

bash พยายามรันคำสั่ง foo โดยตั้งค่า STR เป็นสตริงว่างในสภาพแวดล้อม

ฉันไม่แน่ใจว่าสิ่งนี้จะช่วยชี้แจงหรือว่ามันเป็นเพียงความงงงวย แต่ทราบว่า:

  1. คำสั่งแรกเทียบเท่ากับ: STR "=" "foo",
  2. ที่สองเป็นเช่นเดียวกับSTR "=foo",
  3. STR="" fooและสุดท้ายคือเทียบเท่ากับ

ส่วนที่เกี่ยวข้องของข้อกำหนดภาษา sh ส่วน 2.9.1ระบุ:

"คำสั่งอย่างง่าย" คือลำดับของการกำหนดตัวแปรและการเปลี่ยนเส้นทางที่เป็นทางเลือกในลำดับใดก็ได้ตามด้วยคำและการเปลี่ยนเส้นทางซึ่งสิ้นสุดลงโดยผู้ควบคุม

ในบริบทนั้น a wordคือคำสั่งที่ bash กำลังรัน สตริงใด ๆ ที่มี=(ในตำแหน่งใด ๆ ที่ไม่ใช่ตำแหน่งเริ่มต้นของสตริง) ซึ่งไม่ใช่การเปลี่ยนเส้นทางคือการกำหนดตัวแปรขณะที่สตริงใด ๆ ที่ไม่ใช่การเปลี่ยนเส้นทางและไม่มี=คำสั่งอยู่ ในSTR = "foo", STRไม่ได้เป็นการกำหนดตัวแปร


2
หากคุณมีตัวแปรที่มีชื่อที่มี "-" ข้อผิดพลาดเดียวกันจะเกิดขึ้น ในกรณีนี้วิธีแก้ไขคือการลบ "-"
chomp

1
chomp @ ในกฎ 7b ของส่วน 2.10.10 ของpubs.opengroup.org/onlinepubs/9699919799 "ถ้าตัวละครทั้งหมดที่อยู่ข้างหน้า '=' เป็นชื่อที่ถูกต้อง (ดูที่ชื่อ XBD) โทเค็น ASSIGNMENT_WORD จะส่งกลับ" ตามลิงก์ไปยังส่วน 3.231 ของpubs.opengroup.org/onlinepubs/9699919799เราจะพบ "ในภาษาคำสั่งเชลล์คำที่ประกอบด้วยเครื่องหมายขีดล่างตัวเลขและตัวอักษรจากชุดอักขระแบบพกพาอักขระตัวแรกของชื่อคือ ไม่ใช่ตัวเลข ". ดังนั้นคำFOO-BAR=quxนี้ไม่ใช่การกำหนดตัวแปรเนื่องจากFOO-BARไม่ใช่ชื่อที่ถูกต้อง
William Pursell

2
ฉันขอเสนอรางวัลเพื่ออธิบายคำอธิบายที่ชัดเจนให้กับปัญหาทั่วไปสำหรับผู้เริ่มต้น (และยังสามารถค้นหาได้เร็วขึ้นเมื่อใดก็ตามที่ฉันต้องการลิงก์: D) ขอบคุณที่ทำสิ่งนี้ง่าย!
fedorqui 'ดังนั้นหยุดการทำร้าย'

1
@ fedorqui ขอบคุณ! ฉันไม่เชื่ออย่างเต็มที่ว่านี่เป็นคำอธิบายที่ชัดเจนและฉันมักจะสงสัยว่ามันจะง่ายขึ้นหรือไม่
William Pursell

159

วางช่องว่างรอบ=เครื่องหมาย:

#!/bin/bash 
STR="Hello World" 
echo $STR 

9
นี้เป็นเรื่องตลก แต่เป็นset foo = barเป็นความผิดพลาดที่พบบ่อยในไฟล์ชุดของ Windows เป็นอย่างดีและมีภาษาชุดที่มีการเยาะเย้ยมัน ;-)
โจอี้

ขอบคุณ @joey ฉันติดอยู่ในการเขียนเชลล์สคริปต์ที่ฉันเริ่มต้นตัวแปรด้วยช่องว่างหลังจาก "=" คุณบันทึกวันของฉัน
Lalit Rao

ทำไม bash ไม่ยอมรับตัวเลขในช่องด้านซ้าย เช่น 3 = "Hello World" มันบ่นเกี่ยวกับคำสั่งที่ไม่พบ
Freedo

6

ในโหมดโต้ตอบทุกอย่างดูดี:

$ str="Hello World"
$ echo $str
Hello World

เห็นได้ชัด (!) =เป็นฮันเนสกล่าวว่าไม่มีพื้นที่รอบ ๆ ในกรณีที่มีพื้นที่ว่างรอบ ๆ=แล้วในโหมดโต้ตอบจะให้ข้อผิดพลาดเป็น

ไม่พบคำสั่ง "str"


2
แต่โปรดทราบว่า OP กำลังพูดSTR = "Hello World"ดังนั้นคำตอบนี้ไม่สามารถใช้ได้ที่นี่
fedorqui 'ดังนั้นหยุดการทำร้าย'

@Arkapravo ความหมายของโหมดอินเทอร์แอคทีฟคืออะไรมีส่วนเกี่ยวข้องกับ$เครื่องหมายหรือไม่
Kasun Siyambalapitiya

@KasunSiyambalapitiya โดย "โหมดโต้ตอบ" เขาหมายถึงการพิมพ์คำสั่งเหล่านั้นในเทอร์มินัลจริงไม่ใช่ลงในสคริปต์
numbermaniac

5

ฉันรู้ว่าสิ่งนี้ได้รับคำตอบด้วยคำตอบที่มีคุณภาพสูงมาก แต่ในระยะสั้นคุณไม่สามารถมีช่องว่าง

#!/bin/bash
STR = "Hello World"
echo $STR

ไม่ทำงานเนื่องจากช่องว่างรอบเครื่องหมายเท่ากับ ถ้าคุณต้องวิ่ง ...

#!/bin/bash
STR="Hello World"
echo $STR

มันจะทำงาน


2

เมื่อคุณกำหนดตัวแปรใด ๆ แล้วคุณไม่จำเป็นต้องใส่ในช่องว่างเพิ่มเติม

เช่น

name = "Stack Overflow"  
// it is not valid, you will get an error saying- "Command not found"

ดังนั้นลบช่องว่าง:

name="Stack Overflow" 

และมันจะทำงานได้ดี

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.