Bagaimana saya bisa melacak skrip yang memberi saya "perintah tidak ditemukan" tepat setelah login?


8

Ketika saya masuk, saya memiliki pesan-pesan ini:

-bash: $'\r' : command not found
-bash: $'\r' : command not found
-bash: $'\r' : command not found 

Sangat jelas bahwa ini disebabkan oleh akhiran baris bergaya Windows di beberapa skrip startup, jadi pertanyaan saya adalah: Dapatkah saya melacak skrip yang menyebabkan itu dan bagaimana?


2
Coba lihat file .bashrc, .bash_profile dan profil di direktori home Anda dan / etc / profile
Raman Sailopal

Jawaban:


14

Bash membaca sejumlah file yang berbeda pada saat startup, bahkan tergantung pada bagaimana memulainya ( lihat manual untuk deskripsi ). Lalu ada hal-hal seperti /etc/profile.d/itu yang tidak langsung dibaca oleh shell, tetapi dapat direferensikan dari file startup lainnya di banyak distribusi.

Anda harus melalui semua itu tetapi untungnya, Anda bisa grepmengembalikan kereta. Coba misalnya sesuatu seperti:

grep $'\r' ~/.bashrc ~/.profile ~/.bash_login ~/.bash_profile /etc/bash.bashrc /etc/profile /etc/profile.d/*

Lihat juga Apakah mungkin untuk mengetahui file mana yang diset / ditambahkan ke variabel lingkungan, dan urutan prioritasnya? untuk masalah serupa.


6
Satu lagi tempat yang harus dicari:~/.bash_aliases
Weijun Zhou

1
Pilihan lain adalah menggunakan strace -e open your-shell, dari jawaban Stéphane di sini
Jeff Schaller

5

file (1) dapat membantu di sini juga.

$file *

signin:                                     Python script, ASCII text
signup:                                     Python script, ASCII text, with CRLF line terminators
site_off.htm:                               XML 1.0 document, ASCII text
sitemaps:                                   directory

Saya dapat melihat bahwa signupperlu untuk menghapus Windows CRLF akhir baris sial.

Untuk rekursif langsung seperti /home/usernameAnda mungkin bisa menggabungkan dengan finddan xargs(dan mungkin juga grep):

$ find . | xargs file | grep CR

./foo_data/V: ASCII text, with CR, LF line terminators
./foo_data/Y: ASCII text, with CR, LF line terminators

3

Metode lain adalah dengan mengambil semua skrip startup yang disebutkan, dan menggemakan string yang mengidentifikasi masing-masing di awal masing-masing.

$ head .bashrc
echo "Running bashrc"

Kemudian, saat masuk, Anda akan melihat sesuatu seperti ini:

running bashrc
running bash_aliases
-bash: $'\r' : command not found
-bash: $'\r' : command not found
-bash: $'\r' : command not found 
running something_else

Pada titik itu Anda dapat menyimpulkan bahwa, (dalam contoh di atas) .bash_aliasesberisi akhiran garis yang menyinggung.

Setelah Anda mengidentifikasi file, tetapi baris masalahnya tidak langsung menyerang Anda, Anda dapat menggunakan metode yang sama untuk melacaknya. Gema pesan di tengah file, lalu 3/4 atau 1 / 4s, tergantung pada output. Dengan begitu Anda dapat melacak garis, tergantung pada apakah gema sebelum atau setelah gema Anda.


Ya, metode ini bagus jika seseorang dapat dengan cepat mengotomatiskannya, jika tidak, hampir sama dengan melihat semua file ini.
Denis Sablukov

1
Perhatikan bahwa Anda mungkin ingin juga mengatakan 'selesai menjalankan <file>' di akhir masing-masing. Dalam hal ini tidak terlalu penting kecuali hanya beberapa baris yang memiliki akhiran garis CR, tetapi jika Anda mencari kesalahan lain, itu mungkin ada di .bashrc Anda setelah Anda sumber .bash_aliases.
Ben Millwood

1
Untuk seseorang yang baru belajar men-debug masalah shell, atau ketika tidak semudah mencari '\ r', jawaban ini layak dimiliki di kotak peralatan pengetahuan Anda. Saya mewarisi sistem build kompleks yang merupakan sarang skrip terjalin tikus untuk melakukan build jarak jauh atas SSH. Ini adalah satu-satunya cara untuk melepasnya dan memindahkannya ke wadah Docker.
Scott Prive

1
Kiat umum lainnya - saat berhadapan dengan skrip Bash yang saling terkait, perhatikan di mana Anda menambahkan pernyataan gema dan (apa pun yang sedang Anda lakukan) uji sering. Jika skrip bash digunakan untuk menampilkan string ke STDOUT dan Anda menambahkan pernyataan debug ke STDOUT maka Anda mungkin memecahkan hal yang sedang Anda debug. Terkadang jawabannya adalah menggunakan perintah "logger" untuk menambahkan info / debug ke skrip. Lain kali gunakan STDERR, jika itu merupakan kondisi peringatan.
Scott Prive

@DenisSablukov jika file Anda panjang, dan mencari melalui mereka membutuhkan waktu, metode ini akan membantu Anda mempersempit sumber lebih cepat. Tidak butuh waktu lama untuk mencapai 6 file di bagian atas dan bawah.
user394

3

Saya menganggap bagian yang sulit dari pertanyaan ini bukan "bagaimana saya bisa menemukan carriage return dalam file?" tetapi "bagaimana saya bisa mengetahui file mana yang digunakan bashrc saya?"

Untuk pertanyaan kedua, Anda dapat mencoba sesuatu seperti ini:

bash -x .bashrc

Ini akan menunjukkan semua yang dilakukan bashrc Anda, termasuk semua file yang dirujuk. Itu berisik, tetapi akan membantu Anda melacak file mana yang sedang digunakan.

Kecuali sebenarnya, .bashrcfile saya (dan banyak lainnya) keluar lebih awal jika tidak berjalan secara interaktif, jadi Anda harus mengelabunya agar melewati pemeriksaan itu:

bash -ix .bashrc

Di sini -igaya mode interaktif.

Untuk memahami hanya kasus-kasus di mana Anda sumber file, sesuatu seperti ini bekerja untuk saya tapi saya tidak bisa menjanjikan regex menangkap segalanya:

bash -ix .bashrc 2> >(grep -E '^\+* (\.|source)')

Saya kira Anda mungkin juga menginginkan pesan kesalahan, jadi sesuatu seperti:

bash -ix .bashrc 2> >(grep -E -e '^\+* (\.|source)' -e 'command not found')

Jika karena alasan tertentu tidak ada yang berhasil, saya akan menggunakan strace -e open bashatau sesuatu seperti itu, untuk menemukan setiap kali file dibuka oleh sesi bash Anda. Tapi itu solusi yang lebih berat / berisik.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.