My Oracle Support has landed. Check your links.

So there was a small, inconsequential change in the Oracle Support landscape last week: Oft-maligned-and-yet-somehow-much-beloved Metalink went away, to be replaced by a flashier (hah, I kill me) My Oracle Support. I bet you barely noticed.

One thing that I discovered pretty quickly is that some of my links to old Metalink content no longer worked. Thankfully, the content itself hadn't disappeared, but I had some editing to do in my personal documentation. Here's what I've found:

  • Links referencing metalink2.oracle.com, specifically those of the super-long form https://metalink2.oracle.com/metalink/plsql/f?blahblah:NOT,nnnnnn.n, are broken. This may be temporary, but somehow I doubt it.
  • It appears, however, that shorter metalink2 links (https://metalink2.oracle.com/metalink/plsql/showdoc?db=NOT&id=nnnnnn.n) still resolve.
  • Similarly, links that reference metalink.oracle.com, of the form https://metalink.oracle.com/metalink/plsql/showdoc?db=NOT&id=nnnnnn.n seem to forward to support.oracle.com without issue.
  • The "new way" to format links to My Oracle Support documents is: https://support.oracle.com/CSP/main/article?cmd=show&id=nnnnnn.n&type=NOT
  • These direct links to My Oracle Support documents do not open pages wrapped in the new My Oracle Support interface. This is probably a good thing for lots of people. :-)
  • Links to patches via updates.oracle.com, of the form https://updates.oracle.com/ARULink/PatchDetails/process_form?patch_num=nnnnnnn, are unaffected by the switch to My Oracle Support. Whew.

Anyone notice anything else? Please comment away.

(off-topic aside: I didn't really expect to break a long blog silence with another post about Support. Ah well. Man plans, God laughs.)

The end is near! (for FTP download of Oracle patches)

If you haven't had to download a patch from My Oracle Support lately...lucky you, to have such a smoothly-functioning system! ;-) If you have, however, you may have seen the following notice on the patch download page. Oracle was kind enough to highlight the information in red, which is good, because I usually just ignore the boilerplate:

buh-byeFTPupdates.jpg

I'm not the first to ponder the demise of FTP downloads from Oracle's patch server, but this is the first time I've seen a date (18-SEP-2009) attached to the event. The timing appears to coincide with the imminent retirement of Classic Metalink (which is being met with much wailing and gnashing of teeth, but that's not what this post is about).

Losing FTP access to updates.oracle.com would be a lot more painful if Oracle weren't continuing to allow access via wget. It's pretty clear that Oracle understands that some admins prefer to download patches directly to their servers, and won't force users to access patches solely via a graphical browser. Whatever other concerns I might have about the My Oracle Support transition, this is a piece that's being done right, and I'm grateful.

If you're interested in a solution for using wget to retrieve Oracle patches, I know a guy who wrote a blog post about that very topic a while back...

ASO_ORDER_FEEDBACK_T runs amok, devours database!

There, got that out of my system. I really shouldn't write blog entries after reading The Onion.

A post today on Oracle Mix prompted me to dust off some notes about a problem I ran into a while ago with a table growing out of control in E-Business Suite. Here it is, rescued from the "Hey, that could be a blog post someday" bin:

Observations

  1. The APPS_TS_QUEUES tablespace in our production E-Business Suite instance had grown to the point where it was a significant percentage of the database's overall storage footprint. Not huge, but big enough to be noticeable.
  2. Most of the space seemed to be consumed by the table ASO_ORDER_FEEDBACK_T and its related LOB segments:
    select segment_name "Segment",
    tablespace_name,
    segment_type "Type",
    bytes/1024/1024 "MB"
    from dba_segments
    where segment_name like 'ASO_%FEEDBACK%';
    
    Segment              TABLESPACE_NAME Type  MB
    -------------------- --------------- ----- -----
    ASO_ORDER_FEEDBACK_T APPS_TS_TX_DATA TABLE 3001
    
    select sum(s.bytes)/1024/1024 "MB", count(1) "NumLobs"
    from dba_lobs l, dba_segments s
    where s.segment_name = l.segment_name
    and l.table_name = 'ASO_ORDER_FEEDBACK_T';
    
    MB    NumLobs
    ----- ----------------------
    520   26
    
  3. It appears that all space in ASO_ORDER_FEEDBACK_T is taken up with unprocessed records for the Trade Management (OZF) consumer:
    select consumer_name, msg_state, count(*)
    from aso.aq$aso_order_feedback_t
    group by consumer_name, msg_state;
    
    CONSUMER_NAME MSG_STATE COUNT(*)
    ------------- --------- ----------------------
    OZF           READY     468562
    
  4. On our system, Trade Management (OZF) wasn't even licensed, which probably accounts for the records not being consumed from the queue:
    select app.product_code,
    tl.application_name,
    decode(inst.status, 'I', 'Installed',
    'S', 'Shared',
    'N', 'Not Installed',
    'Wha-huh?') LicStatus,
    inst.patch_level
    from applsys.fnd_product_installations inst,
    applsys.fnd_application app,
    applsys.fnd_application_tl tl
    where app.application_id= inst.application_id
    and tl.application_id= app.application_id
    and app.product_code = 'OZF';
    
    PRODUCT_CODE APPLICATION_NAME LICSTATUS      PATCH_LEVEL
    ------------ ---------------- ---------      -----------
    OZF          Trade Management Not Installed  R12.OZF.A.4
    

Remediation

The following Metalink My Oracle Support Notes address this situation. Although the notes reference to Apps 11.5.x, the conditions and fixes are also applicable to R12, as far as I can tell.

In our case, the fix was easy, since we only had one registered consumer for the queue, and we definitely weren't using that module/application in E-Business Suite:

  1. Delete the QuickCode for OZF as described in Question 1 of Note 181410.1
  2. Purge and rebuild the ASO_ORDER_FEEDBACK_T table as described in Note 740305.1. The process is referenced in Note 181410.1 as well, but it's spelled out much more clearly in Note 740305.1.

Caveats

  • The solution is only this easy if you're not actually using the Order Feedback queue. If you are using the queue, then truncating and rebuilding it is not such a great idea. You might still be able to reclaim some space the slow way, though.
  • While neither document lists this as a requirement, you're probably better off performing this work during a maintenance window, when users aren't doing anything that might be trying to modify the queue.
  • You are going to run through this process on your test system first, right? Good. ;-)

Quick tip: Moving an SSO-integrated E-Business Suite database

Whoops

It seemed simple enough. We were moving our E-Business Suite database to a new server. References to the old database server had to be replaced in a variety of places: Oracle Internet Directory, a handful of tnsnames.ora files, and of course, the context files on the application tier servers. After that, everyone could connect to the database just as they always had. No problems, right?

Well, okay, maybe one small problem: This E-Business Suite system was integrated with Oracle Single Sign-On, and provisioning of users from OID to EBS was not working. Existing users could log in to Oracle Apps, but password changes weren't propagating, and new users in OID were not being created in E-Business Suite. The provisioning trace files on the OID server, located in $ORACLE_HOME/ldap/odi/log, reported the following sort of errors:

Exception Connecting to DB :java.sql.SQLException: Io exception: The Network Adapter could not establish the connection
Error initialzing ProvPLSQLWriter - ODIException: ODI Exception while Initialising PLSQL Writer : DIP_GEN_SPACE_STR
ODIException: Error initialzing ProvPLSQLWriter - ODIException: ODI Exception while Initialising PLSQL Writer : DIP_GEN_SPACE_STR
        at oracle.ldap.odip.prov.ProvPLSQLWriter_2_0.initialise(ProvPLSQLWriter_2_0.java:69)
        at oracle.ldap.odip.prov.ProvOIDToAppSync_2_0.initialise(ProvOIDToAppSync_2_0.java:154)
        at oracle.ldap.odip.engine.ProvThread.runOldVersion(ProvThread.java:534)
        at oracle.ldap.odip.engine.ProvThread.run(ProvThread.java:173)
Error initialzing ProvOIDToAppSync: ODIException: Error initialzing ProvPLSQLWriter - ODIException: ODI Exception while Initialising PLSQL Writer : DIP_GEN_SPACE_STR

Clearly, I had missed a necessary and embarrassingly obvious change in OID. An update to part of the Apps database service identifier (e.g. changing the hostname of the database server) requires an update to the database connect string used by the OID-to-EBS provisioning profile. Otherwise, the provisioning process will be unable to connect to the relocated E-Business Suite database server to update the FND_USER table.

Now what?

I called this an "embarrassingly obvious" miss because the process used to fix the problem is the same one used whenever the Apps password is changed in an SSO-integrated E-Business Suite environment, clearly documented in Section 6.16 of Oracle Application Server 10g with Oracle E-Business Suite Release 11i Troubleshooting. That's a My Oracle Support Note, so I can't reproduce the content here, but in a nutshell, the solution is to use oidprovtool to change the interface_connect_info string for the provisioning profile for the EBS instance in question. After the hostname in the string had been corrected, changes to user records in OID were once again propagating to the EBS database, and new users were able to log in to Oracle Apps.

Two additional notes:

  • Interestingly enough, the R12 version of the My Oracle Support troubleshooting Note, Oracle Application Server 10g with Oracle E-Business Suite Release 12 Troubleshooting, makes no mention of using oidprovtool to change the connection information used by the provisioning profile, but the method described in the 11i note appears to be valid for R12 as well.
  • The "How To" sections of both the 11i and R12 versions of the My Oracle Support notes explain how to dump a list of provisioning profiles to get the application DN required to run oidprovtool.

Hope this helps someone out there. If not, I suspect it'll help me later when I need to look this up again. ;-)

Things I learned this weekend (5/16-17/2009)

The excitement of solving mysteries makes me bad at math

In my last post, I failed to notice that a HugePages_Total of 4645, while satisfyingly greater than zero, is definitely not 8196, the desired and expected value I had configured. Upon reflection, the reason was pretty obvious: the OS will only allocate contiguous blocks of memory for hugepages, and the server had been up for long enough that memory was a bit fragmented. One reboot later, things were much better:

sles10db:~ # cat /proc/meminfo | grep -i huge
HugePages_Total:  8196
HugePages_Free:   8196
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

Autoconfig giveth, and Autoconfig taketh away

When an E-Business Suite system is behaving in a way that suggests one or two mangled (some say "corrupt," but I try not to be judgmental) configuration files, a common first response is to run Autoconfig to see if the system can sort itself out. Running Autoconfig is also frequently necessary during the course of normal maintenance, e.g. during some patching, or when renaming/relocating Oracle Apps nodes. This weekend, I was reminded of an interesting side effect of running Autoconfig. After the process was complete, Grid Control started reporting metric collection errors and "Unknown" status for some components on the application tier nodes. In this case, Autoconfig was just doing its job, generating new versions of configuration files for the apps tier, complete with their original file permissions, which overwrote the permission changes I had made to enable the Grid Control agent to monitor some of the OC4J components. Good thing I keep that list of chmod commands in an easy-to-find reference location.

Oh yeah, and...

I also learned that using wireshark to try to debug a problem with a connection to an Oracle database over VPN is kind of like trying to listen to AM radio in a tunnel. You can tell there's signal there, but good luck making anything of it.

Enabling hugepages on SLES10 x86_64 … not quite the same as SLES9

I feel like a n00b for even posting this, but if part of my goal here is to catalog my mistakes, well, here's one I probably won't make again.

I've been involved in a project to migrate an E-Business Suite database tier from 32-bit to 64-bit RDBMS. Thus far it's been pretty straightforward. One thing had been bugging me, though. Our original test platform was 64-bit SUSE Linux Enterprise Server 9 (SLES9), but a decision was made to upgrade to SLES10 instead. Not a big deal in this case, except for one thing: the settings I'd used in SLES9 to allocate hugepages weren't doing a darn thing in SLES10:

sles10db:~ # grep -i nr_huge /etc/sysctl.conf
vm.nr_hugepages = 8196

sles10db:~ # grep memlock /etc/security/limits.conf
oracle soft memlock 17000000
oracle hard memlock 17000000

Okay so far...

sles10db:~ # grep -i huge /proc/meminfo
HugePages_Total:     0
HugePages_Free:      0
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

sles10db:~ # cat /proc/sys/vm/nr_hugepages
0

Whahuh? Why wasn't my nr_hugepages setting getting picked up from /etc/sysctl.conf? Wrong question, of course. If other settings in that file were being picked up (they were), then clearly something else was clobbering the value I had set. Sure enough, after not much poking around, I found this:

sles10db:~ # grep -i nr_huge /etc/sysconfig/oracle
# /proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
NR_HUGE_PAGES=0

How embarrassing is that? It's even documented in a very official, check-here-first sort of place. Since /etc/init.d/oracle is run long after /etc/init.d/boot.sysctl, the values set in /etc/sysconfig/oracle clearly will clobber anything set in /etc/sysctl.conf. My only defense is that NR_HUGE_PAGES was not included in /etc/sysconfig/oracle on our SLES9 test system, which is why I was setting it in /etc/sysctl.conf in the first place. Of course, we might've been using an old version of orarun.rpm on that server, so it's still a pretty weak excuse. At any rate, changing the setting in /etc/sysconfig/oracle and running rcoracle restart did the job:

sles10db:~ # grep -i nr_huge /etc/sysconfig/oracle
# /proc/sys/vm/nr_hugepages indicates the current number of configured hugetlb
NR_HUGE_PAGES=8196
sles10db:~ # grep -i huge /proc/meminfo
HugePages_Total:  4645
HugePages_Free:   4645
HugePages_Rsvd:      0
Hugepagesize:     2048 kB

Hope this helps someone out there; otherwise, I'll just sit here, alone in my hopefully-temporary idiocy. ;-)

EBS 12.1 now generally available

The Oracle Twitterverse is mildly abuzz (the blogosphere will eventually follow, I'm sure) with the general availability announcement for E-Business Suite Release 12.1. That's a nice start to your Monday morning if you were at the Collaborate '09 keynote. I wasn't, but Twitter got me the news anyway (thanks, Mohan!)

A quick MetalinkMy Oracle Support search on "Release 12.1" reveals a lot of documents that have been updated in the last few days. Of particular interest to me (and maybe to you, which is why I'm posting):

Now, where'd I put my upgrade boots?

How old is that E-Business Suite clone, really?

Small disclaimer: Query output in this post has been altered slightly. The purpose is to obfuscate dates and instance names, not to make the output more interesting.

The boring, easy problem

There are many ways to determine when an E-Business Suite clone was created. To name a few:

  1. Query FND_NODES to find the creation date of nodes in the system:
    SQL> select node_name, creation_date
    2  from fnd_nodes;
    
    NODE_NAME              CREATION_DATE
    ---------------------  ----------------
    JPR12                  29-FEB-10
    
  2. Query FND_APPS_SYSTEM:
    SQL> select name, creation_date
      2  from FND_APPS_SYSTEM;
    
    NAME                   CREATION_DATE
    ---------------------- ---------------
    JPR12                  29-FEB-10
    
  3. Use OAM to find when Site-level profile options such as Two Task, Applications Database ID, or Apps Servlet Agent were set, since these values rarely change over the life of an instance. Querying FND_PROFILE_OPTIONS_VALUES and FND_PROFILE_OPTIONS_TL also reveals this sort of information.
  4. Look at the RESETLOGS_TIME field in V$DATABASE_INCARNATION
  5. Look on the filesystem for log files from adcfgclone.pl ($INST_TOP/admin/log on an R12 apps tier, or $ORACLE_HOME/appsutil/log/$CONTEXT_NAME on the database tier)

None of these options are foolproof, of course. #1 and #2 can be invalidated by running FND_CONC_CLONE.SETUP_CLEAN, profile options can change, and sometimes, people even clean up log files. It's likely that these methods will at least point in the direction of a useful answer, however, and there are no doubt other ways.

None of these methods will answer the really interesting question, though: when did the data in your cloned system diverge from its source?

A more interesting, if somewhat contrived, problem

Imagine you're looking at a cloned E-Business Suite system, and you want to know when its data was copied from the source instance. All you know is that the clone was created from a pile of DVDs labelled "2009 Year-end backups." Thanks to incomplete record-keeping, you don't know what "Year-end" means in this case. It could mean calendar year, fiscal year, or "whenever Accounting reconciled and closed the year." For the sake of argument, assume that the creation dates on the files on the DVDs are also of no help. Furthermore, either because of security policies or an attack of personal integrity, you don't want to abuse your access to the APPS schema to look at data in the Financials, Order Management, or other functional modules to check for record modification dates.

...Hey, I did call this a "somewhat contrived" problem ;-) .

If you're fortunate enough to have just created this clone, and you're running a 10g RDBMS, you can look at the SCN associated with the most recent resetlogs:

SQL> @checkscn
SQL> --Only valid for 10g and up...need to consult smon_scn_time in 9i, no
SQL> --scn_to_timestamp there
SQL> alter session set nls_date_format='DD-MON-YYYY HH24:MI:ss';

Session altered.

SQL> select resetlogs_time, scn_to_timestamp(resetlogs_change#) resetscntime
2 from v$database_incarnation
3 where incarnation#=(select max(incarnation#)
4 from v$database_incarnation);

RESETLOGS_TIME            RESETSCNTIME
-------------------------      ----------------------------------------
29-FEB-2010 02:02:38     15-JAN-10 03.08.22.000000000 PM

Of course, this won't be very helpful if the clone has been up long enough for a lots of SCNs to cycle through:

select resetlogs_time, scn_to_timestamp(resetlogs_change#) resetscntime
*
ERROR at line 1:
ORA-08181: specified number is not a valid system change number
ORA-06512: at "SYS.SCN_TO_TIMESTAMP", line 1

Another possibility: If you're lazy, and not purging sign-on audit data on a regular database, you could get a reasonable guess from FND_LOGINS. What's that? You're not lazy, the scheduled job just hasn't run yet? Oh good, then you can still benefit:

SQL> @checklogin
SQL> alter session set nls_date_format='DD-MON-YYYY HH24:MI:ss';

Session altered.

SQL> select max(start_time)
2 from fnd_logins
3 where start_time < (select resetlogs_time
4 from v$database_incarnation
5 where incarnation#=(select max(incarnation#)
6 from v$database_incarnation))
7 /

MAX(START_TIME)
--------------------------
15-JAN-2010 13:06:42

Or, maybe you have a concurrent program that runs frequently (or even infrequently) in production that hasn't run yet in the clone? That would be convenient!

SQL> alter session set nls_date_format='DD-MON-YYYY HH24:MI:ss';

Session altered.

SQL> set echo on
SQL> select i.concurrent_program_id prog_id,
2 p.user_concurrent_program_name prog_name,
3 i.last_run_date
4 from fnd_conc_prog_onsite_info i, fnd_concurrent_programs_tl p
5 where i.last_run_date is not null
6 and p.concurrent_program_id= i.concurrent_program_id
7 and i.last_run_date < (select resetlogs_time
8 from v$database_incarnation
9 where incarnation#=(select max(incarnation#)
10 from v$database_incarnation))
11 order by i.last_run_date asc
12 /

PROG_ID   PROG_NAME                                LAST_RUN_DATE
--------- ---------------------------------------- ---------------------
(many rows later)
   41566  Compile Security                         15-JAN-2010 11:14:43

Please note that each of the queries above assume that the last resetlogs in the database was performed by adcfgclone.pl dbTier. If you've done another resetlogs since then, adjustments to the queries will be necessary.

I don't claim to have exhaustively considered the options in this situation, and if you have other ideas about how to solve this problem, I'd love to hear them in the comments. Blindingly obvious answers that will make me feel stupid are equally welcome; I can take it. ;-)

Oracle 10gR2 RDBMS for Mac OS X (Intel) has arrived!

This post was written before Snow Leopard (OS X 10.6) shipped. If you're interested in an installation guide for Oracle 10gR2 on Snow Leopard, Raimonds Simanovskis has provided instructions on his blog.

In the wake of a small flurry of announcements yesterday about the release of Oracle 10gR2 for Mac OS X Intel (almost two weeks after April Fools' Day, so knock it off with the jokes already ;-) ), I decided to try a test installation on my Macbook Pro. The good news is that it works, even if you aren't running OS X Server 10.5.4 as specified in the release notes:

OraDBCASuccess.jpg

For the record, this is Mac OS X Leopard, desktop version 10.5.6. I'm still considering whether or not to post an "install guide," since everything more or less worked as advertised. And really, does the Internet need another dozen screenshots of OUI and DBCA doing their usual thing? I feel guilty enough for the screenshot above.

Install guide updates, 12-13 April 2009:

So now what?

Apart from the novelty of it all, is this a worthwhile exercise? I'm not sure yet. I've been using the "Oracle in a VM" approach for a really long time, and I really like the flexibility of being able to play around with system configurations, etc. without worrying about doing any damage to my host system. With snapshots enabled, I don't even have to worry very much about permanently damaging the VM itself. Also, as stated in the release notes  (and called out in this thread on the OTN Apple forum, where hope springs eternal and no one is ever bitter or cranky), the list of supported features for the OS X version is a bit shorter than one might expect. On the other hand, "unsupported" doesn't always mean "won't work," and the memory footprint of a native database is a bit less than that of a full OS + database running in a virtualized environment. My expectation is that for quick testing and tinkering, the native database install could fit a niche, but VM still rules for more advanced stuff like RAC, ASM, 11g, etc.

What's encouraging is that it appears that Oracle hasn't abandoned OS X as a platform. Feature set aside, I suspect they'll need to do more frequent releases before many people would be very comfortable using this in an enterprise setting. But this also opens the possibility of different licensing options...Express Edition for OS X, anyone? OSXXE? ;-)

If someone manages to port this to iPhone, though, let me know. That would rock.

Unix shell geekery: Finding the ten largest residents of a directory

Finding the largest files in a directory on Linux is ridiculously easy, with the right flags to ls:

[oracle@vir demo]$ ls -1srShA | tail
4.0K jptest_mmnl_4899.trc
4.0K jptest_mmon_3011.trc
4.0K jptest_mmon_10186.trc
4.0K jptest_mmon_4897.trc
4.0K jptest_p001_3996.trc
4.0K jptest_p000_3994.trc
4.0K jptest_p000_3034.trc
4.0K jptest_p001_3036.trc
4.0K big directory with annoying name
104K alert_JPTEST.log

But hey, wait…what about that directory? It certainly seems to be conveniently named, almost as if placed there specifically for my follow-up question: What if I what I really want is to know the sizes of the largest files and subdirectories in my current directory? For that, I have to do something a bit more complicated than ls, but less complicated than writing a script:

[oracle@vir demo]$ topten
4.0K    ./jptest_mmnl_4899.trc
4.0K    ./jptest_mmon_10186.trc
4.0K    ./jptest_mmon_3011.trc
4.0K    ./jptest_mmon_4897.trc
4.0K    ./jptest_p000_3034.trc
4.0K    ./jptest_p000_3994.trc
4.0K    ./jptest_p001_3036.trc
4.0K    ./jptest_p001_3996.trc
104K    ./alert_JPTEST.log
529M    ./big directory with annoying name

topten is a shell function defined as follows (you'll probably need to scroll a bit):

[oracle@vir demo]$ type topten
topten is a function
topten ()
{
    find . -maxdepth 1 -not -name '.' -print0 | xargs -0 du -s | sort -n | tail | cut -f2- | awk '{ printf("%s%c", $0, 0) }' | xargs -0 du -sh
}

One could claim that this is ridiculously over-engineered, and I would sheepishly agree. In fact, sharing this on a blog is my only hope of recouping the time spent in constructing the function in the first place. After all, what’s wrong with something as simple as du -s * | sort -n | tail? Well, starting with item #1, below, things just sort of snowball:

  1. In directories with a lot of files, du -s fails with a “too many arguments” error. $APPLCSF/log on an E-Business Suite midtier springs to mind.
  2. Using xargs solves the "too many arguments" problem, but introduces a new one: xargs will misinterpret whitespace in file names as an argument separator, and split the file name. Whitespace in file names? Hey, I work on a Mac. This stuff happens. Users of Cygwin on Windows probably get bitten by this, too.
  3. The use of find -print0 | xargs -0 is a common solution to the "whitespace in filenames" issue.
  4. I like the human-readable output from du -h, but that means I need to pass my top ten files through xargs again, which requires more filtering: cut removes the leading numbers from the output of the first du, and the awk command provides null-terminated output like find's -print0.

Caveats and variations

  • Presumably, this function should work in Bourne-shell variants on any Unix-like system (works fine on Linux and Mac, for example). If you aren't running the GNU versions of the utilities invoked in this function, however, you may need to make some adjustments.
  • It can be expensive to use du. Choose your starting directory with care. If you run this command in the E-Business Suite APPL_TOP, for example, you might want to find something else to do for a few minutes. If you run this command on an already-busy production system, you may also want to find a place to hide from your sysadmins. ;-)
  • If you don’t care about the prettiness of the human-readable file sizes, then you can shorten the function to omit everything after the tail command:
    topten ()
    {
    find . -maxdepth 1 -not -name '.' -print0 | xargs -0 du -s | sort -n | tail
    }
    
  • The function is called topten because the default output for the tail command is 10 lines. Provide the appropriate option to tail to change the output length (tail -5 for 5, tail -20 for 20, etc.)
  • It may be advantageous to add the -x option to du to prevent it from crossing filesystem boundaries.
  • There's probably an easier, and still portable, way to do this. I'm kinda hoping that someone stops by with a comment to tell me what that is. :-)