Không thể thực thi các tập tin .out, bị từ chối cấp phép


11

Tôi đã viết một chương trình C ++ và tuân thủ nó để tạo tệp a.out. Tuy nhiên, bất cứ khi nào tôi cố chạy nó, tôi đều bị từ chối cấp phép. Tôi đọc rằng chúng ta có thể sử dụng sudo, nhưng tôi hoàn toàn không thể làm cho nó hoạt động được. Tôi sử dụng một cái gì đó như, sudo "./a.out" nhưng điều đó cũng không hoạt động.

Chỉnh sửa :

Đây là thông điệp tôi nhận được khi tôi thử "./a.out".

bash: ./a.out: Permission denied

Đầu ra của ls -l a.out là gì? Đầu ra của tập tin a.out là gì? Là thực thi trên thẻ nhớ USB / Harddisk?
JRT

Nó trên Harddisk. Nó cùng một tệp được tạo ngay sau quá trình biên dịch. Tôi không đặt bất kỳ tham số nào khác.
Shamim Hafiz

-rw ------- 1 shamimhafiz shamimhafiz 7721 2011-05-22 23:30 a.out Là đầu ra của ls -l a.out
Shamim Hafiz

Vì vậy, dựa trên đầu ra của ls -l a.out đó là vấn đề về quyền. Nếu bạn làm chmod + x a.out thì hãy thử ./a.out nó có thực thi không? Đầu ra của umask là gì?
JRT

@JRT: Nó không thực thi. Làm "chmod + x a.out" không đưa ra bất kỳ thông báo nào, nhưng có vẻ như nó không có tác dụng. Thử lại "ls -l a.out" một lần nữa vẫn cho thấy điều tương tự.
Shamim Hafiz

Câu trả lời:


18

Thông thường, g++cung cấp cho các quyền thực thi tập tin được tạo. Nếu bạn không vượt qua -otùy chọn, tệp sẽ được đặt tên a.out.

Hai lý do có thể khiến tệp của bạn không có tập bit thực thi, với các giải pháp của chúng:

  1. Các giá trị umask được đặt thành một giá trị như 0133, do đó ngăn cản bit thực thi từ việc thiết lập. Giải pháp: đặt quyền rõ ràng:

    chmod 755 a.out
    
  2. Hệ thống tập tin bạn đang làm việc không hỗ trợ quyền Linux. Đây có thể là trường hợp nếu bạn đặt các tệp trên ổ đĩa flash có định dạng FAT32. Giải pháp: sao lưu các tệp và định dạng tệp thành ext2 hoặc gắn ổ đĩa bằng fmask=0022hoặc umask=0022(bỏ qua fmask). Xem các tùy chọn Mount cho phần chất béo trên trang hướng dẫn gắn kết để biết thêm chi tiết.

Đối với các tập lệnh bash không có tập lệnh thực thi, bạn có thể chạy bash file.sh. Một tính năng như vậy tồn tại cho tất cả các tệp có nội dung thực thi (tệp được biên dịch và tệp có bộ dòng shebang #!/path/to/interpreter). Để thực thi các tệp mà không có tập bit thực thi, hãy sử dụng tệp đặc biệt /lib/ld-linux.so.2(hoặc /lib/ld-linux-x86-64.so.2cho các ứng dụng 64 bit) để chạy chương trình như vậy:

/lib/ld-linux-x86-64.so.2 a.out

Câu trả lời này thú vị hơn, chỉ cần thêm, cách tôi đã cài đặt Ubuntu qua Windows và một thư mục có tên được tạo trên ổ C (ổ đĩa cài đặt windows). Ổ đĩa này được định dạng là FAT32. Điều này có thể có một cái gì đó để làm với điều đó?
Shamim Hafiz

1
Bạn đã thực hiện cài đặt Wubi ( C:\Ubuntuđã được tạo). Đây không phải là vấn đề trừ khi bạn đặt tệp vào "C:" chứ không phải cài đặt Ubuntu. Nếu bạn không sử dụng Windows hoặc có nhiều dung lượng đĩa, tôi khuyên bạn nên cài đặt Ubuntu trên một phân vùng chuyên dụng. Và một lần nữa, NTFS / FAT32 KHÔNG hỗ trợ cho phép Linux, vì vậy bạn có thể chạy sudo chown user file, chmod 755 filenó sẽ không làm việc. Bạn thực sự cần một hệ thống tập tin EXT cho điều đó.
Lekensteyn

3
Câu chuyện tương tự, không có hệ thống tệp Windows nào hỗ trợ quyền truy cập tệp Linux. Bạn nên đặt các tệp trên một hệ thống tệp được định dạng EXT.
Lekensteyn

1
Vì vậy, chỉ cần làm việc trên một thư mục thuộc về Ubuntu thì nên thực hiện thủ thuật, phải không? Ý tôi là, tôi không nên sử dụng các thư mục không thuộc Cấu trúc hệ thống tệp của Ubuntus?
Shamim Hafiz

3
Chính xác, chỉ cần ở lại ~, tôi tạo ~/projectsvà đặt tất cả các dự án của tôi vào đó, bạn có thể làm điều tương tự.
Lekensteyn

5

.out là một phần mở rộng khác thường. Thông thường, điều này thường biểu thị một tệp "theo dõi đầu ra".

Kiểm tra cú pháp của bạn mà bạn đang sử dụng để biên dịch

ví dụ

gcc myfile.c /usr/lib/libsomelibrary.a -o outputfilename

hoặc có thể

g++ myfile.cpp -lm -o outputfilename

Bạn có thể kiểm tra xem bit thực thi có được đặt trên tệp không

ls -l a.out

hoặc bạn chỉ có thể buộc bit thực thi

chmod +x a.out

sau đó bạn có thể chạy tập tin của bạn

./a.out

hoặc đơn giản

a.out

Có lẽ bạn cũng nên kiểm tra xem tệp đầu ra đã được viết chính xác dưới dạng nhị phân chưa

I E

file a.out

Điều này sẽ báo cáo định dạng của tệp - tập lệnh hoặc tệp nhị phân

Bạn hiếm khi cần thực thi với quyền root trừ khi bạn đã hạn chế người có thể chạy tệp thực thi.

Nếu bạn đã biên dịch dưới dạng root (ví dụ: sudo make) hoặc có một Makefile đã cài đặt thực thi như root thì tôi có thể đề nghị bạn lấy lại quyền khi người dùng đăng nhập

I E

sudo chown fred:fred a.out

tức là thay thế "fred" bằng id người dùng của bạn.


Cảm ơn vì thông tin. Tôi thực sự đăng nhập với tư cách là người dùng duy nhất và tôi cho rằng tôi là người dùng chính. Tôi không chắc lắm, tại sao tôi vẫn cần sử dụng xác thực quản trị. Làm thế nào tôi có thể loại bỏ tùy chọn này để tôi luôn có thể chạy các tệp.
Shamim Hafiz

cập nhật - hy vọng để làm rõ và trả lời câu hỏi của bạn.
fossfreedom

a.out là một tính năng kế thừa của trình biên dịch để nó tạo ra một tên tệp có thể dự đoán được nếu bạn không yêu cầu. Đây không phải là vấn đề về quyền, mà là sự hiểu lầm về cách trình biên dịch và C ++ hoạt động.
SpamapS

Linux / Unix không dựa vào phần mở rộng tệp để xác định loại tệp. Thông thường các tập tin thực thi không có phần mở rộng nào cả. Ngoài ra, định dạng để thực thi một tệp không khác nhau giữa các shell nói chung. Tất cả các shell nên hoạt động với ./a.out trừ khi đó là một số shell kỳ lạ.
JRT

1
Gunner - vui lòng sao chép và dán đầu ra hoàn chỉnh trong thiết bị đầu cuối bắt đầu bằng lệnh biên dịch của bạn, tiếp theo là ls -l, chmod + x và cuối cùng là thực thi. Vui lòng xác nhận tên của bạn bằng cách nhập "whoami"
fossfreedom

4

chỉ cần sao chép thư mục vào thư mục nhà của bạn và nó sẽ hoạt động. Bạn có thể đang cố gắng chạy nó trên một ổ đĩa ngoài hoặc một cái gì đó.


0

Cách giải quyết cho các hệ thống tập tin FAT trong câu trả lời đầu tiên

"Đây có thể là trường hợp nếu bạn đặt các tệp vào ổ flash có định dạng FAT32. Giải pháp: (...) gắn ổ đĩa với fmask = 0022 hoặc umask = 0022 (bỏ qua fmask)."

thông thường không hoạt động - mặc định cho umask chủ yếu là 0022, vì vậy điều này không thay đổi bất cứ điều gì.

Tuy nhiên, mặc định của tham số gắn kết khác không cho phép thực thi nhị phân một cách hiệu quả, đặc biệt nếu hệ thống tập tin FAT được gắn kết là người dùng không root: noexec

Vì vậy, chỉ cần gắn các ổ đĩa có định dạng FAT với tùy chọn execnhư vậy:

sudo mount -o exec /dev/sd.. /mountpoint

(điều này thường phải được thực hiện dưới dạng root, do đó là "sudo") và bạn sẽ có thể thực thi nhị phân trực tiếp từ đó.


-2

Tôi muốn rằng chương trình của bạn không có hàm 'main ()', như thể nó đã làm, trình biên dịch của bạn sẽ tạo ra một tệp thực thi a.out. Ngay bây giờ nó chỉ là một tệp đối tượng chứa đầy mã, nhưng không có điểm vào. main () là một tên hàm đặc biệt trong C và C ++, yêu cầu trình biên dịch tạo một chương trình thay vì chỉ các tệp đối tượng có thể được liên kết với một chương trình hoặc thư viện.

Tôi rất muốn biết dòng lệnh nào bạn đã sử dụng để tạo tệp này, vì trình biên dịch c ++ của GNU GCC, g ++, sẽ không cho phép tôi tạo một chương trình đơn giản với chức năng chính:

#include <iostream>

using namespace std;

void no_main()
{
  cout << "Hello World" << endl;
}

$ g++ hello.cc
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 0 has invalid symbol index 11
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 1 has invalid symbol index 12
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 2 has invalid symbol index 2
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 3 has invalid symbol index 2
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 4 has invalid symbol index 11
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 5 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 6 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 7 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 8 has invalid symbol index 2
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 9 has invalid symbol index 2
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 10 has invalid symbol index 12
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 11 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 12 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 13 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 14 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 15 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 16 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 17 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 18 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 19 has invalid symbol index 13
/usr/bin/ld.bfd.real: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 20 has invalid symbol index 21
/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/../../../crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

Tuy nhiên, nếu tôi thay đổi 'void no_main' thành 'int main' thì nó hoạt động:

$ g++ hello.cc
$ ./a.out
Hello World

5
Nếu anh ta không có chức năng chính , nó sẽ không liên kết và do đó nó sẽ không tạo ra tệp a.out .
JRT
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.