Tại sao sh (không phải bash) phàn nàn về các hàm được định nghĩa trong .bashrc của tôi?


11

Tôi nhận được cái này khi tôi mở một phiên cuối:

sh: lỗi nhập định nghĩa hàm cho `read.json '

sh: lỗi nhập định nghĩa hàm cho `ts-project '

sh không thích các chức năng này bởi vì chúng trông giống như:

read.json(){
   ::
}

ts-project(){
   ::
}

câu hỏi thực sự là - tại sao shchạm / giải thích các tệp này? Tôi đang dùng MacOS và thấy điều này trước đây, đó là một bí ẩn. Tôi nghĩ chỉ có bash mới tải những tập tin này.

cập nhật : bash và sh không có gì khác thường. Khi tôi gõ bash vào terminal, tôi nhận được điều này:

alex$ bash
beginning to load .bashrc
finished loading .bashrc
bash-3.2$ 

Khi tôi gõ shvào terminal, tôi nhận được điều này:

alex$ sh
sh: error importing function definition for `read.json'
sh: error importing function definition for `ts-project'
sh-3.2$ 

1
Có lẽ / bin / sh bash trên hệ thống đó?
Jeff Schaller

1
Không ai trong số họ nguồn nhau, tôi phát hiện ra rằng đó là một thực hành tồi một cách khó khăn. tuy nhiên, ~ / .profile đang tìm nguồn cung cấp tệp bash được chia sẻ, vậy có lẽ shnguồn nào là tệp .profile?
Alexander Mills

1
Thông tin về việc có tệp ~ / .profile nguồn tệp được chia sẻ có vẻ quan trọng đối với tôi.
Jeff Schaller

3
Điều tôi muốn nói là / bin / sh bị bash là có thể nó được liên kết hoặc liên kết cứng với bash. Bash sau đó mô phỏng sh, nhưng cũng có nguồn ~ / .profile. Tôi chỉ không biết làm thế nào các gói OSX sh và bash.
Jeff Schaller

3
Chúng được xây dựng từ cùng một bashnguồn, cái kia STRICT_POSIX, cái kia không có nó.
mosvy

Câu trả lời:


20

Lỗi đó xảy ra khi bashgiả mạo như một vỏ POSIX cố gắng nhập các hàm đó từ môi trường, chứ không phải khi tải chúng bằng cách diễn giải một tệp như ~/.bashrcthế. Ví dụ đơn giản:

foo.bar(){ true; }; export -f foo.bar; bash --posix -c true
bash: error importing function definition for `foo.bar'

Tôi đã mong đợi bashkhông tải các chức năng từ môi trường khi ở chế độ posix, nhưng chỉ và phàn nàn khi tên của chúng chứa các ký tự vui nhộn.

Lưu ý rằng bashcũng sẽ chạy trong chế độ posix khi biến POSIXLY_CORRECThoặc POSIX_PEDANTICmôi trường được đặt hoặc khi nó được biên dịch với --enable-strict-posix-default/ STRICT_POSIX.

Sau này có vẻ là trường hợp đối với /bin/shtrên hệ điều hành MacOS (nhìn ở đây cho PRODUCT_NAME = sh), nơi tôi mong đợi lỗi này cũng kích hoạt khi sử dụng chức năng thư viện như popen(3)hay system(3).


3
Cách khắc phục: không xuất các hàm trong môi trường. Đó là tính năng chống bash dẫn đến (hay đúng hơn, đơn giản là) Shellshock và nó đáng lẽ phải bị xóa, nhưng không phải vì mọi người đang dại dột sử dụng nó. Đừng là một trong số họ.
R .. GitHub DỪNG GIÚP ICE

Thực tế là bash nhập các hàm ngay cả khi được gọi shlà nguyên nhân khiến lỗ hổng shellshock / bashdoor trở nên tồi tệ hơn rất nhiều .
Stéphane Chazelas

Xem thêm SHELLOPTS=posix-o posixđể biết các cách khác để kích hoạt chế độ posix.
Stéphane Chazelas

Cũng lưu ý rằng set -a/ set -o allexportcũng khiến bash xuất tất cả các chức năng (và nếu được gọi là sh, nguyên nhân POSIXLY_CORRECTsẽ được đặt và xuất!)
Stéphane Chazelas

( sh -anguyên nhân POSIXLY_CORRECTđược đặt và xuất; set -asau khi shkhông -abắt đầu không xuất POSIXLY_CORRECTvì nó được đặt trước -acó hiệu lực).
Stéphane Chazelas

5

Để trả lời phần về lý do read.jsonts-projectkhông phải là tên hàm di động:

Theo POSIX, một định nghĩa hàm phải được đặt tên theo

một từ chỉ bao gồm dấu gạch dưới, chữ số và bảng chữ cái từ bộ ký tự di động. Ký tự đầu tiên của tên không phải là chữ số.

Còn được gọi là định danh , trong C lingo. Hoặc trong regex:[_a-zA-Z][0-9_a-zA-Z]*


Nhưng POSIX không cấm việc triển khai chấp nhận các tên khác cho các chức năng, vì vậy bash không phải áp đặt các hạn chế đó khi ở chế độ POSIX. Tên hàm chia sẻ không gian tên giống như đối số lệnh, vì vậy không có lý do gì để chấp nhận bất cứ điều gì (như zsh/ rc/ fish...)
Stéphane Chazelas

@ StéphaneChazelas: Tôi biết, nhưng ở chế độ POSIX có nghĩa là gì, nếu không "rũ bỏ tất cả các tiện ích mở rộng", như trong "không âm thầm chấp nhận chúng"?
dùng2394284

@ user2394284 chắc chắn không có nghĩa là trong bashhoặc nó sẽ không nhập các chức năng từ môi trường trong khi ở chế độ POSIX, không được yêu cầu bởi thông số POSIX ;-)
mosvy

@mosvy: Vâng, rõ ràng là bash đã thất bại ở đâu đó trên đường đi - tôi sẽ nói rằng đó là một vỏ POSIX đơn giản, đó sẽ là một lỗi.
dùng2394284

0

Vì vậy, điều gây ra nó là tôi đang tìm nguồn cung cấp một số tập lệnh bash trong tệp ~ / .bashrc của mình như vậy:

for f in "$HOME/.oresoftware/bash/"*; do
   . "$f"
done;

Vì vậy, tôi chỉ thay đổi nó thành:

for f in "$HOME/.oresoftware/bash/"*; do
  if [[ "$(basename "$0")" != 'sh' ]]; then
      # source only if not using sh
      . "$f"
  fi
done;

Vì vậy, về mặt lý thuyết nếu nó được gọi shthì nó sẽ không cố gắng tìm nguồn các tệp đó, nhưng không chắc liệu nó có hoạt động 100% không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.