অপরিবর্তনীয় বৈশিষ্ট্য সেট সহ ফাইলগুলি কীভাবে অনুসন্ধান করবেন?


17

কনফিগার অডিটিং কারণে, আমি অপরিবর্তনীয় বৈশিষ্ট্য সেট রয়েছে (এমন chattr +i) ফাইলগুলির জন্য আমার ext3 ফাইল সিস্টেম অনুসন্ধান করতে সক্ষম হতে চাই । findএটির মতো বা এর মতো কোনও বিকল্প আমি খুঁজে পাচ্ছি না । এই মুহুর্তে, আমি ভয় করছি আমাকে lsattrপ্রতিটি ডিরেক্টরিতে আউটপুট পার্স করার জন্য আমার নিজস্ব স্ক্রিপ্ট লিখতে হবে । এমন কোনও স্ট্যান্ডার্ড ইউটিলিটি রয়েছে যা আরও ভাল উপায় সরবরাহ করে?


আমার স্পষ্ট করে বলা উচিত ছিল যে আমার ক্ষেত্রে, আমি কেবল কনফিগার ব্যবস্থাপনার জন্য নিরীক্ষণ করছি, অনুপ্রবেশ সনাক্তকরণের জন্য নয়, সুতরাং আমাকে নতুন লাইনগুলি নিয়ে খুব বেশি চিন্তা করার দরকার নেই, কারণ আমি জানি যে ফাইলগুলির সাথে আমি যে ফাইলের সাথে কাজ করছি সেগুলি থাকবে না তাদের। তা সত্ত্বেও, নিউলাইন ইস্যুটি মাথায় রাখার মতো, সুতরাং আমি আমার প্রশ্নটি যেমন রাখি তেমনি রেখে দেব।
16.11 এ প্রস্থান করুন

উত্তর:


9

grepকমান্ড টু lsattrকমান্ডটি পাইপ করে এটি আংশিকভাবে সম্পন্ন করা যায় ।

lsattr -R | grep +i

যাইহোক, আমি বিশ্বাস করি যখন আপনি সমগ্র উল্লেখ ext3ফাইল সিস্টেম অনুসন্ধান জড়িত হতে পারে /proc, /devএবং কিছু অন্যান্য ডিরেক্টরি যা প্রতিবেদন করলে কিছু ত্রুটি আপনি শুধু চাই উপেক্ষা করার। আপনি সম্ভবত কমান্ডটি চালাতে পারেন,

lsattr -R 2>/dev/null | grep -- "-i-"

"-I-" এর সাথে আরও পরিষ্কারভাবে মেলে দেখার জন্য আপনি পিসিআরই সুবিধা grepব্যবহার করে কিছুটা আরও কঠোর করতে চাইতে পারেন grep

lsattr -R 2>/dev/null | grep -P "(?<=-)i(?=-)"

এটি তখন এর মতো পরিস্থিতির জন্য কাজ করবে:

$ lsattr -R 2>/dev/null afile | grep -P "(?<=-)i(?=-)"
----i--------e-- afile

কিন্তু অসম্পূর্ণ। যদি অবিচ্ছেদ্য পতাকার চারপাশে অতিরিক্ত বৈশিষ্ট্য সক্ষম করা থাকে, তবে আমরা সেগুলির সাথে মেলে না files

$ lsattr -R 2>/dev/null afile* | grep -P "(?<=-)i(?=-)"
----i--------e-- afile
-------------e-- afile-i-am

আমরা এর মতো আরও কিছুটা আরও শক্ত করে তুলতে পারি:

$ lsattr -a -R 2>/dev/null afile* | grep -P "(?<=-)i(?=-).* "
----i--------e-- afile

তবে এটি এখনও খানিকটা ভঙ্গুর এবং আপনার ফাইল সিস্টেমের মধ্যে থাকা ফাইলগুলির উপর নির্ভর করে অতিরিক্ত টুইট করার প্রয়োজন হবে। যেমন উল্লেখ না @StephaneChazeles মন্তব্য উল্লেখ করেছে যে এই উপরোক্ত প্যাটার্ন বাইপাস করার জন্য একটি ফাইল নাম দিয়ে নতুন লাইন অন্তর্ভুক্তি দ্বারা মোটামুটি সহজে gamed যাবে grep

তথ্যসূত্র

https://groups.google.com/forum/#!topic/alt.os.linux/LkatROg2SlM


1
হা আমি একই থ্রেড পড়েছিলাম এবং পোস্ট করতে চলেছিলাম। আমি আমার অতিরিক্তগুলি আপনার পরিবর্তে যুক্ত করব।
slm

@ এসএলএম, যে কোনও পরিবর্তন করতে আপনাকে সবচেয়ে স্বাগত জানানো হয়েছে :)
রমেশ

2
সম্ভবত অডিটিংয়ের পক্ষে ভাল নয় কারণ কেউ এই পদ্ধতির সাথে ফাইলের নামে নতুন লাইন অক্ষর দ্বারা একটি অপরিবর্তনীয় ফাইল নকল বা লুকিয়ে রাখতে পারে। এছাড়াও, ফাইলের নামগুলির নাম রাখা অস্বাভাবিক নয় -i-(বর্তমানে আমি যে সিস্টেমে লগ ইন করছি সে সিস্টেমে 34 জন রয়েছে)। আপনি সম্ভবত -aবিকল্পটিও চাইবেন
স্টাফেন চেজেলাস

1
কৌতূহলের বাইরে, +iপ্রথম উদাহরণে কী হওয়ার কথা? এটি আমার পক্ষে কাজ করে না। এছাড়াও, গ্রেপিং -i-ধরে নেওয়া হয় যে সংশ্লেষগুলি i(যেমন a) সংলগ্ন প্রদর্শিত আনসেট হয় না।
বঞ্চিত

1
কেন সহজ জন্য গ্রেপ না ^....i? বা কমপক্ষে এমন কিছু ^[^ ]*iযদি iপঞ্চম বাদে অন্য অবস্থানে থাকতে পারে।
রুসলান

6

স্ক্রিপ্টের উদ্দেশ্যটি নিরীক্ষণ করা হচ্ছে তা দেওয়া সুনির্দিষ্ট ফাইল নামগুলির সাথে সঠিকভাবে ডিল করা গুরুত্বপূর্ণ, যেমন নিউলাইনগুলি যুক্ত নামের সাথে। এটি ব্যবহার করা অসম্ভব করে তোলেlsattr একসাথে একাধিক ফাইলগুলিতে করা , যেহেতু আউটপুট lsattrসেই ক্ষেত্রে অস্পষ্ট হতে পারে।

আপনি একবারে একটি ফাইলের সাথে পুনরাবৃত্তি করতে findএবং কল করতে পারেন lsattr। যদিও এটি বেশ ধীর হবে।

find / -xdev -exec sh -c '
  for i do
     attrs=$(lsattr -d "$i"); attrs=${attrs%% *}
     case $attrs in
       *i*) printf "%s\0" "$i";;
     esac
  done' sh {} +

আমি পার্ল, পাইথন বা রুবির মতো কম কৃপণ ভাষা ব্যবহার করার এবং lsattrনিজের কাজটি করার পরামর্শ দিচ্ছি । lsattrএকটি FS_IOC_GETFLAGSআইওসিটিএল সিস্কল জারি করে এবং ফাইলের ইনোড পতাকাগুলি পুনরুদ্ধার করে পরিচালনা করে । এখানে পাইথন প্রুফ অফ-কনসেপ্ট রয়েছে।

#!/usr/bin/env python2
import array, fcntl, os, sys
FS_IOC_GETFLAGS = 0x80086601
EXT3_IMMUTABLE_FL = 0x00000010
count = 0
def check(filename):
    fd = os.open(filename, os.O_RDONLY)
    a = array.array('L', [0])
    fcntl.ioctl(fd, FS_IOC_GETFLAGS, a, True)
    if a[0] & EXT3_IMMUTABLE_FL: 
        sys.stdout.write(filename + '\0')
        global count
        count += 1
    os.close(fd)
for x in sys.argv[1:]:
    for (dirpath, dirnames, filenames) in os.walk(x):
        for name in dirnames + filenames:
            check(os.path.join(dirpath, name))
if count != 0: exit(1)

1
অবগতির জন্য আমার সিস্টেমের FS_IOC_GETFLAGSহয় 0x80046601
অ্যান্টনোন

1
এর মান FS_IOC_GETFLAGSনির্ভর করে sizeof(long)। সি কি ম্যাক্রো বিস্তৃতি খুঁজে বের করতে যেমন দেখুন নিম্নলিখিত ব্যাশ কমান্ড প্রয়োগ করুন: gcc -E - <<< $'#include <linux/fs.h>\nFS_IOC_GETFLAGS' | tail -n1। : আমি এটা থেকে নিম্নোক্ত অভিব্যক্তি পেয়েছিলাম (((2U) << (((0 +8)+8)+14)) | ((('f')) << (0 +8)) | (((1)) << 0) | ((((sizeof(long)))) << ((0 +8)+8))), যা সহজসাধ্য (2U << 30) | ('f' << 8) | 1 | (sizeof(long) << 16)
রুসলান

এই ফিফোর উপর chokes।
রোডওল

3

স্বেচ্ছাসেবী ফাইলের নাম (নিউলাইন অক্ষরগুলি সহ এটি সহ) ডিল করতে, সাধারণ কৌশলটি এর.//. পরিবর্তে ফাইলগুলি ভিতরে সন্ধান করা .। কারণ //সাধারণত যখন ডিরেক্টরি ট্রি ঢোঁড়ন ঘটবে না পারে, আপনি নিশ্চিত যে একটি //সংকেত একটি নতুন ফাইলের নাম শুরু find(অথবা এখানে lsattr -R) আউটপুট।

lsattr -R .//. | awk '
  function process() {
    i = index(record, " ")
    if (i && index(substr(record,1,i), "i"))
      print substr(record, i+4)
  }
  {
    if (/\/\//) {
      process()
      record=$0
    } else {
      record = record "\n" $0
    }
  }
  END{process()}'

দ্রষ্টব্য যে আউটপুটটি এখনও নতুন লাইন পৃথক থাকবে। আপনার যদি এটি পোস্ট-প্রক্রিয়া করার প্রয়োজন হয়, আপনাকে এটি মানিয়ে নিতে হবে। উদাহরণস্বরূপ, আপনি -v ORS='\0'এটি জিএনইউতে ফিড করতে সক্ষম হতে একটি যুক্ত করতে পারেন xargs -r0

আরও মনে রাখবেন যে lsattr -R(কমপক্ষে 1.42.13) ফাইলের পতাকা PATH_MAX (সাধারণত 4096) এর চেয়ে বড় যার পতাকাগুলি রিপোর্ট করতে পারে না , তাই কেউ লুকিয়ে রাখতে পারে তার অভিভাবক ডিরেক্টরিটি (বা পথের উপাদানগুলির দিকে নিয়ে যাওয়ার যে কোনও পথ উপাদানকে সরিয়ে নিয়ে এমন অপরিবর্তনীয় ফাইলটি এটি নিজেকে অপরিবর্তনীয় হিসাবে বাদে) একটি খুব গভীর ডিরেক্টরিতে পরিণত করে।

চারপাশের কাজগুলি এর findসাথে ব্যবহার করা হবে -execdir:

find . -execdir sh -c '
  a=$(lsattr -d "$1") &&
    case ${a%% *} in
      (*i*) ;;
      (*) false
    esac' sh {} \; -print0

এখন, -print0এটি পোস্ট-প্রসেসেবল, তবে আপনি যদি সেই পাথগুলির সাথে কিছু করার ইচ্ছা করেন তবে মনে রাখবেন যে PATH_MAX এর চেয়ে বড় ফাইল পাথগুলিতে যে কোনও সিস্টেম কল এখনও ব্যর্থ হতে পারে এবং ডিরেক্টরি উপাদানগুলি অন্তরালে নামকরণ করা যেতে পারে।

আমরা যদি কোনও ডিরেক্টরি ট্রিতে একটি নির্ভরযোগ্য প্রতিবেদন পেতে পারি যা অন্যের দ্বারা সম্ভবত এটি লিখিত হয়, lsattrকমান্ড নিজেই অন্তর্ভুক্ত রয়েছে আরও কয়েকটি বিষয় যা আমাদের উল্লেখ করতে হবে:

  • lsattr -R .ডিরেক্টরি ট্রিটিকে যেভাবে অনুসরণ করে , এটি জাতি শর্তের সাপেক্ষে। .ডান মুহুর্তে সিমলিংকের সাহায্যে কয়েকটি ডিরেক্টরি প্রতিস্থাপনের মাধ্যমে ডিরেক্টরি গাছের বাইরে থাকা ডিরেক্টরি গাছের বাইরের ডিরেক্টরিতে এটি নামানো যায়।
  • এমনকি lsattr -d fileএকটি জাতি শর্ত আছে। এই বৈশিষ্ট্যগুলি কেবল নিয়মিত ফাইল বা ডিরেক্টরিতে প্রযোজ্য। সুতরাং lsattrএকটি করে lstat()চেক করার জন্য যে ফাইল ডান ধরনের এবং তারপর করে প্রথম open()দ্বারা অনুসরণ ioctl()বৈশিষ্ট্যাবলী পুনরুদ্ধার করতে। তবে এটি কল করে (না O_NOCTTY) open()ছাড়াই O_NOFOLLOW। কেউ প্রতিস্থাপন করতে পারে fileকরার জন্য একটি সিমবলিক লিঙ্ক দিয়ে /dev/watchdogমধ্যবর্তী উদাহরণস্বরূপ lstat()এবং open()এবং রিবুটের সিস্টেম কারণ। এটি open(O_PATH|O_NOFOLLOW)অনুসরণ করা উচিত fstat(), openat()এবং ioctl()এখানে বর্ণের পরিস্থিতি এড়াতে।

2

আমাকে সঠিক দিকের দিকে নির্দেশ করার জন্য রমেশ, এসএমএল এবং স্টাফেনকে ধন্যবাদ (আমি -Rস্যুইচটি মিস করছি lsattr)। দুর্ভাগ্যক্রমে, এখনও পর্যন্ত কোনও উত্তরই আমার পক্ষে সঠিকভাবে কাজ করে নি।

আমি নিম্নলিখিত নিয়ে এসেছি:

lsattr -aR .//. | sed -rn '/i.+\.\/\/\./s/\.\/\///p'

এটি কোনও ফাইল যখন অপরিবর্তনীয় হিসাবে উপস্থিত হয় তখন উপস্থিত হতে নিউলাইনগুলি ব্যবহার করা থেকে রক্ষা করে। এটি এমন ফাইলগুলির বিরুদ্ধে সুরক্ষা দেয় না যা অপরিবর্তনীয় হিসাবে সেট করা থাকে এবং তাদের ফাইলের নামগুলিতে নতুন লাইন থাকে। তবে যেহেতু মূলত এই জাতীয় ফাইলটি তৈরি করতে হবে, আমি নিশ্চিত হতে পারি যে আমার ব্যবহারের ক্ষেত্রে এই ফাইলগুলি আমার ফাইল সিস্টেমে নেই। (মূল ব্যবহারকারীর সাথে আপোস করা হতে পারে এমন ক্ষেত্রে অনুপ্রবেশ সনাক্তকরণের জন্য এই পদ্ধতিটি উপযুক্ত নয়, তবে তারপরেও একই সিস্টেমের lsattrইউটিলিটি ব্যবহার করা হচ্ছে না যা একই মূল ব্যবহারকারীদের দ্বারাও মালিকানাধীন is)


কেবল একটি রুট কোনও ফাইলে অপরিবর্তনীয় বিট যুক্ত করতে পারে তবে সম্ভাব্যভাবে অন্যান্য ব্যবহারকারীরা পরবর্তীকালে সেই ফাইলগুলির নাম পরিবর্তন করতে পারে যা এই ফাইলগুলিতে নেতৃত্ব দেয়, সুতরাং ফাইলের পথে নতুন লাইন থাকতে পারে। এছাড়াও একজন ব্যবহারকারী এমন একটি ফাইলের পথ তৈরি করতে পারেন (অপরিবর্তনীয় নয়) যা আপনার স্ক্রিপ্টটিকে অন্য ফাইলটি অপরিবর্তনীয় বলে ভাবতে বোকা বানাবে।
স্টাফেন চেজেলাস

2

ব্যবহার find -exec, খুব ধীর আউটপুট পার্স lsattrহয় একভাবে যে অবিশ্বস্তls , পাইথন হিসেবে ব্যবহার গিলেজ দ্বারা উত্তর জন্য অবিরাম চয়ন প্রয়োজন ioctlকিনা পাইথন ইন্টারপ্রেটার 32- বা 64 বিট উপর নির্ভর করে ...

হাতের সমস্যাটি কম-বেশি নিম্ন-স্তরের, সুতরাং আসুন নিম্ন স্তরের দিকে যান: স্ক্রিপ্টিং ভাষা হিসাবে সি ++ তেমন খারাপ নয় :) বোনাস হিসাবে এটি সি প্রিপ্রসেসরের সম্পূর্ণ ক্ষমতা সহ সিস্টেম সি হেডারগুলিতে অ্যাক্সেস পায়।

নিম্নলিখিত প্রোগ্রামটি অপরিবর্তনীয় ফাইলগুলির জন্য অনুসন্ধান করে, একটি ফাইল সিস্টেমের মধ্যে থাকা, অর্থ্যাৎ কখনই মাউন্ট পয়েন্টগুলি অতিক্রম করে না। আপাত গাছটি অনুসন্ধান করতে, প্রয়োজন অনুসারে মাউন্ট পয়েন্টগুলি অতিক্রম FTW_MOUNTকরে, nftwকলটিতে পতাকা সরিয়ে ফেলুন । এছাড়াও এটি symlinks অনুসরণ করে না। তাদের অনুসরণ করতে FTW_PHYSপতাকাটি সরান ।

#define _FILE_OFFSET_BITS 64
#include <iostream>
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <sys/stat.h>
#include <ftw.h>

bool isImmutable(const char* path)
{
    static const int EXT3_IMMUTABLE_FLAG=0x10;

    const int fd=open(path,O_RDONLY|O_NONBLOCK|O_LARGEFILE);
    if(fd<=0)
    {
        perror(("Failed to open file \""+std::string(path)+"\"").c_str());
        return false;
    }
    unsigned long attrs;
    if(ioctl(fd,FS_IOC_GETFLAGS,&attrs)==-1)
    {
        perror(("Failed to get flags for file \""+std::string(path)+"\"").c_str());
        close(fd);
        return false;
    }
    close(fd);
    return attrs & EXT3_IMMUTABLE_FLAG;
}

int processPath(const char* path, const struct stat* info, int type, FTW* ftwbuf)
{
    switch(type)
    {
    case FTW_DNR:
        std::cerr << "Failed to read directory: " << path << "\n";
        return 0;
    case FTW_F:
        if(isImmutable(path))
            std::cout << path << '\n';
        return 0;
    }
    return 0;
}

int main(int argc, char** argv)
{
    if(argc!=2)
    {
        std::cerr << "Usage: " << argv[0] << " dir\n";
        return 1;
    }
    static const int maxOpenFDs=15;
    if(nftw(argv[1],processPath,maxOpenFDs,FTW_PHYS|FTW_MOUNT))
    {
        perror("nftw failed");
        return 1;
    }
}

-1

আউটপুটটিকে গ্রেপ-তে পাইপ করার পরিবর্তে আউটপুটটির প্রথম ক্ষেত্রের সাথে কেবল 'আমি' মেলে শুধু কেন জাজ ব্যবহার করবেন না?

lsattr -Ra 2>/dev/null /|awk '$1 ~ /i/ && $1 !~ /^\// {print}'

আসলে, আমি প্রতিদিন এটি ক্রোন এর মাধ্যমে কয়েকশ সার্ভারে / ইত্যাদি ডিরেক্টরি স্ক্যান করতে এবং আউটপুটকে সিসলগে প্রেরণ করতে চালাচ্ছি। আমি তখন স্প্লঙ্কের মাধ্যমে একটি দৈনিক প্রতিবেদন তৈরি করতে পারি:

lsattr -Ra 2>/dev/null /etc|awk '$1 ~ /i/ && $1 !~ /^\// {print "Immutable_file="$2}'|logger -p local0.notice -t find_immutable

আপনার প্রথম কোড স্নিপেটে একটি টাইপ রয়েছে এবং আপনার দ্বিতীয়টি আমার সিস্টেমে অপরিবর্তনীয় ফাইলগুলি খুঁজে পাবে না।
ছাড়ুন

প্রথম কমান্ডে স্থির টাইপ। সম্ভবত দ্বিতীয়টি কোনও অপরিবর্তনীয় ফাইল খুঁজে পাচ্ছে না কারণ কোনও নেই?
রুটদেব

আমি লক্ষ্য করিনি দ্বিতীয় কমান্ডটি কেবল সন্ধান করছে /etc। তবে উভয় কমান্ডই ভুলভাবে একটি অ-পরিবর্তনযোগ্য ফাইল খুঁজে touch `"echo -e "bogus\n---------i---e-- changeable"`"
পেয়েছিল

এটি আমার মূল পোস্টে বলে যে আমি ক্রোনের মাধ্যমে / ইত্যাদি ডিরেক্টরিতে স্ক্যান করতে চালাচ্ছি। আপনি পোস্টটি চালানোর আগে কমান্ড বা কমান্ডটি না পড়লে আমি এটিকে সহায়তা করতে পারি না। এবং হ্যাঁ, আপনি যদি মনে করেন যে কোনও অনুসন্ধানকে বোকা বানানোর জন্য আপনি সম্ভবত একটি এজ কেস তৈরি করতে পারেন তবে আপনি যেহেতু আমার মূল কমান্ডের টাইপটি প্রদর্শন করতে এত তাড়াতাড়ি ছিলেন (শেষটি অনুপস্থিত), আমি এটি উল্লেখ করব আপনার কমান্ড লিখিত হিসাবে কাজ করে না তাই কিছু তৈরি করবে না! :-)
রুটদেব

আমার খারাপ। এটি চেষ্টা করুন:touch "`echo -e 'bogus\n---------i---e-- changeable'`"
ছাড়ুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.